├── Source ├── fonts │ ├── Roobert-11-Medium-table-22-22.png │ └── Roobert-11-Medium.fnt ├── pdxinfo └── main.lua ├── README.md └── LICENSE /Source/fonts/Roobert-11-Medium-table-22-22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gingerbeardman/mandala/HEAD/Source/fonts/Roobert-11-Medium-table-22-22.png -------------------------------------------------------------------------------- /Source/pdxinfo: -------------------------------------------------------------------------------- 1 | name=Mandala 2 | author=Matt Sephton 3 | description=Logic Operation Pixel Patterns 4 | bundleID=com.gingerbeardman.mandala 5 | version=1.01 6 | buildNumber=101 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mandala 2 | 3 | A little playground for testing pixel logic patterns on [Playdate](https://play.date) 4 | 5 | ![https://i.imgur.com/OQHNwm7.gif](https://i.imgur.com/OQHNwm7.gif) 6 | 7 | Generating a screen takes a couple of seconds on Playdate hardware as it requires per-pixel processing of the entire 400x240 screen = 96,000 pixels. As such, these effects are not currently suitable for real-time use, but should rather be pre-rendered or cached in some way. There may be some optimisations that can be made to improve the situation. 8 | 9 | Or you can run it full speed in Playdate Simulator. 10 | 11 | ## More info 12 | - https://twitter.com/aemkei/status/1378106731386040322 13 | 14 | ## License 15 | [MIT LICENSE](LICENSE) 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Matt Sephton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Source/main.lua: -------------------------------------------------------------------------------- 1 | -- https://twitter.com/aemkei/status/1378106731386040322?s=46&t=vAQ328oQf-s81-tV9T-wKQ 2 | 3 | import "CoreLibs/sprites" 4 | 5 | local gfx = playdate.graphics 6 | 7 | gfx.setBackgroundColor(gfx.kColorBlack) 8 | playdate.display.setRefreshRate(10) 9 | 10 | local playerSprite = nil 11 | local W = playdate.display.getWidth() 12 | local H = playdate.display.getHeight() 13 | 14 | fnt = gfx.font.new("fonts/Roobert-11-Medium") 15 | 16 | local imgSprite = gfx.image.new(W,H) 17 | local imgHud = gfx.image.new(W//3,H//8) 18 | 19 | spr = gfx.sprite.new( imgSprite ) 20 | spr:moveTo( 0,0 ) 21 | spr:setCenter( 0,0 ) 22 | spr:add() 23 | 24 | hud = gfx.sprite.new( imgHud ) 25 | hud:moveTo( 15,190 ) 26 | hud:setCenter( 0,0 ) 27 | hud:add() 28 | 29 | function p_xor_mod(x,y,z) return (x ~ y) % z end 30 | function p_or_mod(x,y,z) return (x | y) % z end 31 | function p_mul_and(x,y,z) return (x * y) & z end 32 | function p_xor_lsh(x,y,z) return (x ~ y) << z end 33 | function p_mul_mod(x,y,z) return (x * z) % (y+1) end 34 | -- function p_mul_mod_offset(x,y,z) return ((x-W//2) * z) % ((y-H//2)+1) end 35 | 36 | local allFuncs = {p_xor_mod, p_or_mod, p_mul_and, p_xor_lsh, p_mul_mod} --p_mul_mod_offset 37 | local allLabels = {"(x ~ y) %% %s", "(x | y) %% %s", "(x * y) & %s", "(x ~ y) << %s", "(x * %s) %% y", "((x-200) * %s) %% (y-120)"} 38 | 39 | local current = 1 40 | local f = allFuncs[current] 41 | local ft = allLabels[current] 42 | local delta = 1 43 | local var = 5 44 | local changed = true 45 | 46 | function drawPixels() 47 | gfx.lockFocus(imgSprite) 48 | for x=0,W do 49 | for y=0,H do 50 | p = f(x,y, var) 51 | if p == 0 then 52 | gfx.setColor(gfx.kColorWhite) 53 | else 54 | gfx.setColor(gfx.kColorBlack) 55 | end 56 | gfx.drawPixel(x,y) 57 | end 58 | end 59 | gfx.unlockFocus() 60 | 61 | changed = false 62 | end 63 | 64 | function drawHud() 65 | gfx.lockFocus(imgHud) 66 | gfx.clear(gfx.kColorWhite) 67 | fnt:drawText(string.format(ft,var), 5,5) 68 | gfx.unlockFocus() 69 | 70 | changed = false 71 | end 72 | 73 | function math.ring(a, min, max) 74 | if min > max then 75 | min, max = max, min 76 | end 77 | return min + (a-min)%(max-min) 78 | end 79 | 80 | function math.ring_int(a, min, max) 81 | return math.ring(a, min, max+1) 82 | end 83 | 84 | function setVar(m) 85 | var = m 86 | changed = true 87 | end 88 | 89 | function funcNext() 90 | current = math.ring_int(current+1,1,#allFuncs) 91 | ft = allLabels[current] 92 | 93 | changed = true 94 | 95 | return allFuncs[current] 96 | end 97 | 98 | function funcPrev() 99 | current = math.ring_int(current-1,1,#allFuncs) 100 | ft = allLabels[current] 101 | 102 | changed = true 103 | 104 | return allFuncs[current] 105 | end 106 | 107 | local myInputHandlers = { 108 | 109 | AButtonDown = function() 110 | delta = 5 111 | end, 112 | AButtonUp = function() 113 | delta = 1 114 | end, 115 | BButtonDown = function() 116 | delta = 10 117 | end, 118 | BButtonUp = function() 119 | delta = 1 120 | end, 121 | upButtonDown = function() 122 | setVar(var + delta) 123 | end, 124 | downButtonDown = function() 125 | setVar(var - delta) 126 | end, 127 | leftButtonDown = function() 128 | f = funcPrev() 129 | end, 130 | rightButtonDown = function() 131 | f = funcNext() 132 | end, 133 | 134 | cranked = function(change, acceleratedChange) 135 | end, 136 | } 137 | playdate.inputHandlers.push(myInputHandlers) 138 | 139 | function playdate.update() 140 | if changed == true then 141 | drawPixels() 142 | drawHud() 143 | end 144 | 145 | gfx.sprite.update() 146 | end 147 | -------------------------------------------------------------------------------- /Source/fonts/Roobert-11-Medium.fnt: -------------------------------------------------------------------------------- 1 | tracking=1 2 | space 3 3 | ! 2 4 | " 6 5 | # 14 6 | $ 11 7 | % 15 8 | & 13 9 | ' 2 10 | ( 5 11 | ) 5 12 | * 8 13 | + 10 14 | , 3 15 | - 8 16 | . 2 17 | / 9 18 | 0 12 19 | 1 5 20 | 2 11 21 | 3 12 22 | 4 12 23 | 5 11 24 | 6 12 25 | 7 11 26 | 8 11 27 | 9 12 28 | : 2 29 | ; 4 30 | < 9 31 | = 11 32 | > 9 33 | ? 9 34 | @ 18 35 | A 13 36 | B 11 37 | C 14 38 | D 12 39 | E 10 40 | F 10 41 | G 14 42 | H 12 43 | I 2 44 | J 5 45 | K 12 46 | L 9 47 | M 15 48 | N 11 49 | O 15 50 | P 10 51 | Q 15 52 | R 10 53 | S 11 54 | T 12 55 | U 12 56 | V 12 57 | W 18 58 | X 11 59 | Y 10 60 | Z 11 61 | [ 5 62 | \ 9 63 | ] 5 64 | ^ 7 65 | _ 11 66 | ` 3 67 | a 9 68 | b 10 69 | c 10 70 | d 10 71 | e 10 72 | f 7 73 | g 10 74 | h 9 75 | i 3 76 | j 4 77 | k 10 78 | l 2 79 | m 16 80 | n 9 81 | o 11 82 | p 10 83 | q 10 84 | r 6 85 | s 8 86 | t 7 87 | u 9 88 | v 8 89 | w 14 90 | x 9 91 | y 10 92 | z 9 93 | { 6 94 | | 2 95 | } 6 96 | ~ 10 97 | ¥ 10 98 | … 12 99 | ™ 16 100 | ‼ 6 101 | © 15 102 | ® 15 103 | � 15 104 | Ⓐ 18 105 | Ⓑ 18 106 | 🌐 18 107 | › 14 108 | ▸ 12 109 | ⊙ 18 110 | ‘ 3 111 | ’ 3 112 | “ 6 113 | ” 6 114 | ac 0 115 | ad 0 116 | ae 0 117 | af -1 118 | ag 0 119 | ap 0 120 | ar 1 121 | at -1 122 | au 0 123 | av -1 124 | aw -1 125 | ay -1 126 | b, -1 127 | b. -1 128 | bl 0 129 | br 0 130 | bu 0 131 | by -1 132 | ca 0 133 | ch 0 134 | ck 0 135 | d, -1 136 | d. 0 137 | da 0 138 | dc 0 139 | de 0 140 | dg 0 141 | do 0 142 | dt 0 143 | du 0 144 | dv 0 145 | dw 0 146 | dy 0 147 | e, -1 148 | e. -1 149 | ea 0 150 | ei 0 151 | el 0 152 | em 0 153 | en 0 154 | ep 0 155 | er 0 156 | et -1 157 | eu 0 158 | ev -1 159 | ew -1 160 | ey -1 161 | f, -2 162 | f. -2 163 | fa -1 164 | fe -1 165 | ff -2 166 | fi 0 167 | fl -1 168 | fo -2 169 | g, 0 170 | g. 0 171 | ga 0 172 | ge 0 173 | gg 0 174 | gh 0 175 | gl 0 176 | go 0 177 | hc 0 178 | hd 0 179 | he 0 180 | hg 0 181 | ho 0 182 | hp 0 183 | ht -1 184 | hu 0 185 | hv -1 186 | hw -1 187 | hy -1 188 | ic -1 189 | id -1 190 | ie -1 191 | ig -1 192 | io -1 193 | ip -1 194 | it -2 195 | iu -1 196 | iv -1 197 | j, 0 198 | j. 0 199 | ja 0 200 | je 0 201 | jo 0 202 | ju 0 203 | ka -2 204 | kc -2 205 | kd -2 206 | ke -2 207 | kg -2 208 | ko -2 209 | la 0 210 | lc 0 211 | ld 0 212 | le 0 213 | lf 0 214 | lg 0 215 | lo 0 216 | Lo -1 217 | lp 0 218 | lq 0 219 | lu 0 220 | lv 0 221 | lw 0 222 | ly 0 223 | ma 0 224 | mc 0 225 | md 0 226 | me 0 227 | mg 0 228 | mn 0 229 | mo 0 230 | mp 0 231 | mt -1 232 | mu 0 233 | mv -1 234 | my -1 235 | nc 0 236 | nd 0 237 | ne 0 238 | ng 0 239 | no 0 240 | np 0 241 | nt -1 242 | nu 0 243 | nv -1 244 | nw -1 245 | ny -1 246 | o, -2 247 | o. -1 248 | ob 0 249 | of -2 250 | oh 0 251 | oj -2 252 | ok 0 253 | ol 0 254 | om 0 255 | on 0 256 | op 0 257 | or 0 258 | ou 0 259 | ov -1 260 | ow -1 261 | ox -1 262 | oy -1 263 | p, -1 264 | p. -1 265 | pa 0 266 | ph 0 267 | pi 0 268 | pl 0 269 | pp 0 270 | pu 0 271 | qu 0 272 | r, -3 273 | r. -2 274 | ra -1 275 | rd -1 276 | re -1 277 | rg -1 278 | rk 0 279 | rl 0 280 | rm 0 281 | rn 0 282 | ro -2 283 | rq -1 284 | rr 0 285 | rt -1 286 | rv 0 287 | ry 0 288 | s, -1 289 | s. -1 290 | sh 0 291 | st -1 292 | su 0 293 | t, 0 294 | t. 1 295 | ta 1 296 | td 0 297 | te 0 298 | th 1 299 | ti 1 300 | tl 1 301 | to 0 302 | ua 0 303 | uc 0 304 | ud 0 305 | ue 0 306 | ug 0 307 | uo 0 308 | up 1 309 | uq 0 310 | ur 1 311 | ut 0 312 | uv 0 313 | uw 0 314 | uy 0 315 | v, -2 316 | v. -2 317 | va 0 318 | vb 0 319 | vc -1 320 | vd -1 321 | ve -1 322 | vg -1 323 | vo -1 324 | vv 0 325 | vy -1 326 | w, -2 327 | w. -1 328 | wa -1 329 | wd -1 330 | we -1 331 | wg -1 332 | wh 0 333 | wo -1 334 | wx -1 335 | xa -1 336 | xe -1 337 | xo -1 338 | y, -3 339 | y. -2 340 | ya -1 341 | yc -1 342 | yd -1 343 | ye -1 344 | Yo -2 345 | yo -1 346 | LO -2 347 | AT -3 348 | AY -3 349 | // -4 350 | /d -2 351 | /p -1 352 | tp 1 353 | t: 1 354 | /w -1 --------------------------------------------------------------------------------