liquidream.paste.lol / mag1k-eye.lua · 4 months ago·

-- mag1k-eye
-- by paul nicholas
function _init()
	palt(0, false)
	tick = 0
	-- rds constants
	zmax = 4
	dpi = 20
	e = dpi * 2.5
	mu = 1 / 3
	max_colours = 5  
	-- drawing variables
	size = 3  -- initial radius
	c = 1     -- initial height/color
  b = 1     -- brush type (1=circle, 2=square)
	edit=true -- start in editor mode
	-- enable mouse
	poke(24365,1)
  
	init_edit()
end

function _update60()
 -- read gpio
 io = peek(0x5f80)
 -- 1 = switch to edit mode
 -- 2 = switch to circle tool
 -- 3 = switch to square tool
 -- 4 = switch to stereogram mode
 -- 5 = save image (edit/stereo)
 -- 6 = undo/redo toggle
 -- 7 = clear the canvas

 -- mode switch
 switch=false
 if (btnp(❎)) edit=not edit switch=true
 if (io==1and not edit) edit=true switch=true
 if (io==4 and edit) edit=false switch=true

 if switch then
 	if edit then
 	 -- restore
 	 memcpy(0,0x8000,0x2000)
 	 init_edit()
 	else
 	 -- backup
 	 memcpy(0x8000,0,0x2000)
 	 init_stereo() 	 
 	end
 end

 -- draw
 if edit then
  update_edit()
 else
  update_stereo()
 end

 -- reset gpio
 poke(0x5f80,0)
end

function save_check()
  if io==5 then 
  -- save image (edit/stereo)
  extcmd("screen") 
 end 
end
-->8
-- editor
c=1
s=5
function init_edit() 
 pal(15,0)
 --?"\^!5f100█ˇ5●?7☉"
 ?"\^!5f100█ˇ5●?70☉"
end
function update_edit()
 x=stat(32)
 y=stat(33)
 
 if(btnp(➡️))s+=1
 if(btnp(⬅️))s-=1
 s=mid(3,s+stat(36),20)
 if(btnp(⬆️))c+=1
 if(btnp(⬇️))c-=1
 c=mid(c,6)
 
 -- brush type
 if (io==2) b=1
 if (io==3) b=2
 --undo/redo
 if btnp(🅾️) or io==6 then
  memcpy(0x8000,0,0x2000)
  poke(0x5f55,0)
  memcpy(0,0xa000,0x2000)
 	poke(0x5f55,0x60)
  memcpy(0xa000,0x8000,0x2000)
 end
 -- clear
 if io==7 then
  poke(0x5f55,0)
	cls()
	poke(0x5f55,0x60)
 end

 if stat(34)>0 then
	 if stat(34)>1 then
	  c=sget(x,y)
	 else
   if not click then
    click=true
    -- backup curr draw to extra user mem
    memcpy(0xa000,0,0x2000)
   end
   painting=true
   -- set draw target to sprite data
   poke(0x5f55,0)
   if b==1 then
 	  circfill(x,y,s,c)
   else
    rectfill(x-s,y-s,x+s,y+s,c)
   end
   -- reset draw target to screen
	 poke(0x5f55,0x60)
  end
 else
  if click then
    click=false
  end
  painting=false
 end
 -- draw spritesheet/image to screen
 spr(0,0,0,16,16) 
 save_check() 
 -- show tool preview 
 if b==1 then
  circfill(x,y,s,c)
  circ(x,y,s,painting and 6 or 8)
 else
  rectfill(x-s,y-s,x+s,y+s,c)
  rect(x-s,y-s,x+s,y+s,painting and 6 or 8)
 end
 ?c,x-1,y-2
end

-->8
-- stereo mode

function init_stereo() 
	-- rnd cols
 off=flr(rnd(15))-15
 for i=1,6 do
  pal(i,i+off,1)
 end
	-- gen stereo
 rds(max_colours) 
end

function update_stereo() 
 spr(0,0,0,16,16)
 save_check()
end

-->8
-- stereogram calculations
-- by gearfo
-- https://www.lexaloffle.com/bbs/?tid=34529
--
-- this is the algorithm of
-- inglis, thimbleby and
-- witten (1994)
-- displaying 3d images: algorithms for single-image random-dot stereograms, ieee computer 27(10)

function rds(cmax)
-- read a depth map from the
-- sprite sheet and write a
-- random dot stereogram
-- back onto the sprite sheet
 if (cmax < 2) cmax = 2
 if (cmax > 16) cmax = 16
 local far = sep(0)
 local j,i
 for j = 0, 127 do -- loop over lines of the depth map
  same = {} 
  for i = 0, 127 do
   same[i] = i
  end
  for i = 0, 127 do
   local z = sget(i, j) -- depth at i,j
   if(z > 8) z = 8 -- hacky bug fix
   z = z / zmax
   local s = sep(z)
   local left = flr(i - s / 2)
   local right = left + s
   local visible = false
   if 0 <= left and right < 128 then
    visible = false
    local t = 1
    while true do
     local zt = z + 2*(2-mu*z)*t/(mu*e) 
     pixl = sget(flr(i-t),j)/zmax
     pixr = sget(flr(i+t),j)/zmax
     visible = pixl < zt and pixr < zt
     t+=1
     if not visible or zt >=1 then
      break
     end
    end
    if visible then
     local l = same[left]
     while l != left and l != right do
      if l < right then
       left = l
       l = same[left]
      else
       same[left] = right
       left = right
       l = same[left]
       right = l
      end
     end
     same[left] = right
    end
   end
  end
  for i = 127,0,-1 do
   if same[i] == i then
    sset(i, j, rnd(cmax))
   else
    sset(i, j, sget(same[i], j))
   end
  end
 end 
 -- set draw target to sprite data
 poke(0x5f55,0)
 circfill(64 - far / 2, 123, 3, 0)
 circfill(64 + far / 2, 123, 3, 0)
 -- reset draw target to screen
 poke(0x5f55,0x60)
end

function sep(z)
 -- return stereo separation for depth z
 return flr(((1 - mu * z) * e / (2 - mu * z))+0.401) 
 -- hack to get same rounding in orig code using flr
end