Advertisement
adriweb

AntiCaster non-euclidian raytracer Nspire Lua port

Nov 20th, 2015
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.06 KB | None | 0 0
  1. --antiCaster
  2. --by Cumred_Snektron for SDL2, ported by Ivoah
  3.  
  4. -- Some Lua optimizations by Adriweb
  5.  
  6. local mathsin, mathcos, mathsqrt, mathfloor = math.sin, math.cos, math.sqrt, math.floor
  7.  
  8. function pow(a, b) return a^b end
  9.  
  10. --vec2.c
  11. function vec2_add(v0, v1, out)
  12.     return {x = v0.x + v1.x, y = v0.y + v1.y}
  13. end
  14.  
  15.  
  16. function vec2_addscale(v0, v1, scale)
  17.     return {x = v0.x + v1.x*scale, y = v0.y + v1.y*scale}
  18. end
  19.  
  20. function vec2_normalize(v0)
  21.     length = mathsqrt(v0.x*v0.x + v0.y*v0.y)
  22.     return {x = v0.x/length, y = v0.y/length}
  23. end
  24.  
  25. function vec2_rotate(v0, angle)
  26.     return {x = v0.x * mathcos(-angle) - v0.y * mathsin(-angle), y = v0.x * mathsin(-angle) +  v0.y * mathcos(-angle)}
  27. end
  28.  
  29. --map.c
  30.  
  31. function map_init(width, height, defaultblock)
  32.     map = {width = width, height = height, map = {}}
  33.     for i=0, width*height - 1 do
  34.         map.map[i] = defaultblock
  35.     end
  36.     return map
  37. end
  38.  
  39. function map_setblockat(map, x, y, block)
  40.     if x >= 0 and x < map.width and y >= 0 and y < map.height then
  41.         map.map[y*map.width+x] = block
  42.     end
  43. end
  44.  
  45. function map_getblockat(map, x, y)
  46.     if (x >= 0 and x < map.width and y >= 0 and y < map.height) then
  47.         return map.map[y*map.width+x]
  48.     end
  49.     return false
  50. end
  51.  
  52. --game.c
  53. player_movespeed = 0.5
  54. player_rotspeed = 0.007
  55.  
  56. p = {}
  57. m = {}
  58.  
  59. function _init()
  60.     p.pos = {x = 5, y = 5}
  61.     p.dir = {x = -1., y = 0.}
  62.  
  63.     defaultwall = {type = 0, spacex = 1., spacey = 1.}
  64.  
  65.     m = map_init(20, 20, defaultwall)
  66.  
  67.     bluewall = {type = 1, spacex = 1., spacey = 1.}
  68.     greenwall = {type = 2, spacex = 1., spacey = 1.}
  69.     redwall = {type = 3, spacex = 1., spacey = 1.}
  70.     compressedwall = {type = 0, spacex = 1., spacey = .1}
  71.  
  72.     for i=0, 20 - 1 do
  73.         map_setblockat(m, i, 0, bluewall)
  74.         map_setblockat(m, i, 19, bluewall)
  75.         map_setblockat(m, 0, i, bluewall)
  76.         map_setblockat(m, 19, i, bluewall)
  77.     end
  78.  
  79.     map_setblockat(m, 10, 10, greenwall)
  80.     map_setblockat(m, 11, 10, compressedwall)
  81.     map_setblockat(m, 12, 10, compressedwall)
  82.     map_setblockat(m, 13, 10, compressedwall)
  83.     map_setblockat(m, 14, 10, greenwall)
  84.  
  85.     map_setblockat(m, 11, 16, redwall)
  86. end
  87.  
  88. function on.arrowKey(key)
  89.     b = map_getblockat(m, mathfloor(p.pos.x), mathfloor(p.pos.y))
  90.  
  91.     x = 0
  92.  
  93.     if key == "left" then x = -5
  94.     elseif key == "right" then x = 5 end
  95.  
  96.     p.dir = vec2_rotate(p.dir, x*player_rotspeed)
  97.  
  98.     dir = p.dir
  99.     dirx = {x = dir.y, y = -dir.x}
  100.  
  101.     if (b) then
  102.         dir.x = dir.x*b.spacex
  103.         dir.y = dir.y*b.spacey
  104.         dirx.x = dirx.x*b.spacex
  105.         dirx.y = dirx.y*b.spacey
  106.     end
  107.  
  108.     if key == "up" then
  109.         p.pos = vec2_addscale(p.pos, dir, player_movespeed)
  110.     elseif key == "down" then
  111.         p.pos = vec2_addscale(p.pos, dir, -player_movespeed)
  112.     --elseif key == "left" then
  113.     --  p.pos = vec2_addscale(p.pos, dirx, -player_movespeed)
  114.     --elseif key == "right" then
  115.     --  p.pos = vec2_addscale(p.pos, dirx, player_movespeed)
  116.     end
  117.  
  118.     platform.window:invalidate()
  119. end
  120.  
  121. function sign(x)
  122.   return (x<0 and -1) or 1
  123. end
  124.  
  125. function tri(a, b, c)
  126.     if a then
  127.         return b
  128.     else
  129.         return c
  130.     end
  131. end
  132.  
  133. function nexthit(r)
  134.     hb = map_getblockat(m, r.mapx, r.mapy)
  135.     s = tri(hb, {x = hb.spacex, y = hb.spacey}, {x = 1, y = 1})
  136.  
  137.     dir = r.dir
  138.     r.dir.x = r.dir.x*s.x
  139.     r.dir.y = r.dir.y*s.y
  140.  
  141.     r.dir = vec2_normalize(r.dir)
  142.  
  143.     deltadistx = mathsqrt(1 + (r.dir.y * r.dir.y) / (r.dir.x * r.dir.x))
  144.     deltadisty = mathsqrt(1 + (r.dir.x * r.dir.x) / (r.dir.y * r.dir.y))
  145.  
  146.     stepx = sign(r.dir.x)
  147.     stepy = sign(r.dir.y)
  148.  
  149.     sidedistx = tri(stepx < 0, (r.orig.x - r.mapx), (r.mapx + 1.0 - r.orig.x)) * deltadistx
  150.     sidedisty = tri(stepy < 0, (r.orig.y - r.mapy), (r.mapy + 1.0 - r.orig.y)) * deltadisty
  151.  
  152.     d = {x = 0, y = 0}
  153.  
  154.     if (sidedistx < sidedisty) then
  155.         d.x = r.dir.x * sidedistx
  156.         d.y = r.dir.y * sidedistx
  157.         r.mapx = r.mapx + stepx
  158.         r.side = 0
  159.     else
  160.         d.x = r.dir.x * sidedisty
  161.         d.y = r.dir.y * sidedisty
  162.         r.mapy = r.mapy + stepy
  163.         r.side = 1
  164.     end
  165.     r.orig.x = r.orig.x + d.x
  166.     r.orig.y = r.orig.y + d.y
  167.     r.distance = r.distance + mathsqrt(pow(d.x/s.x, 2) + pow(d.y/s.y, 2))
  168.  
  169.     r.dir = dir
  170.     return r
  171. end
  172.  
  173. -- cast the ray.
  174. function cast(r)
  175.     hit = {}
  176.     hit.hit = false
  177.  
  178.     r.mapx = mathfloor(r.orig.x)
  179.     r.mapy = mathfloor(r.orig.y)
  180.     r.distance = 0
  181.  
  182.     for i=0, 99 do
  183.         r = nexthit(r)
  184.  
  185.         hb = map_getblockat(m, r.mapx, r.mapy)
  186.         if hb and hb.type > 0 then
  187.             hit.distance = r.distance
  188.             hit.hitblock = hb
  189.             hit.side = r.side
  190.             hit.hit = true
  191.             hit.point = {x = r.orig.x, y = r.orig.y}
  192.             return hit
  193.         end
  194.     end
  195.     return hit
  196. end
  197.  
  198. function vline(gc, x, y0, y1, c)
  199.     gc:setColorRGB(c)
  200.     gc:drawLine(x, y0, x, y1)
  201. end
  202.  
  203. function on.resize(w, h)
  204.     pww, pwh = w, h
  205.     platform.window:setBackgroundColor(0)
  206. end
  207.  
  208. function on.paint(gc)
  209. -- If running on OS 3.9, you can just call the platform.window:setBackgroundColor(0) in on.resize.
  210. --    gc:setColorRGB(0,0,0)
  211. --    gc:fillRect(0, 0, pww, pwh)
  212.  
  213.     plane = vec2_normalize({x = p.dir.y*0.66, y = -p.dir.x*0.66})
  214.  
  215.     for x=0, pww-1 do
  216.         cam = 2*x/pww - 1
  217.  
  218.         r = {}
  219.         r.orig = {x = p.pos.x, y = p.pos.y}
  220.         r.dir = {x = p.dir.x + plane.x * cam, y = p.dir.y + plane.y * cam}
  221.  
  222.         hit = cast(r)
  223.  
  224.         if hit.hit then
  225.  
  226.             dist = hit.distance/mathsqrt(1+cam*cam)
  227.  
  228.             lineh = mathfloor(pwh/dist)
  229.  
  230.             if hit.hitblock.type == 1 then
  231.                 vline(gc, x, pwh/2 - lineh/2, pwh/2 + lineh/2, 0x0000FF - hit.side * 0x000022)
  232.             elseif hit.hitblock.type == 2 then
  233.                 vline(gc, x, pwh/2 - lineh/2, pwh/2 + lineh/2, 0x00FF00 - hit.side * 0x002200)
  234.             else
  235.                 vline(gc, x, pwh/2 - lineh/2, pwh/2 + lineh/2, 0xFF0000 - hit.side * 0x220000)
  236.             end
  237.         end
  238.     end
  239. end
  240.  
  241. _init()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement