MoonlightOwl

Hologram Viewer 0.7.1-en

Feb 3rd, 2017
3,253
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --       Hologram Viewer v0.7.1
  2. -- 2017 (c) Totoro (aka MoonlightOwl)
  3. --         computercraft.ru
  4.  
  5. local fs = require('filesystem')
  6. local shell = require('shell')
  7. local com = require('component')
  8. local args = { ... }
  9.  
  10. local loc = {
  11.   ERROR_NO_FILENAME = "[ERROR] You must give some filename to show. Like: show myfile.3dx",
  12.   ERROR_WRONG_FILE_FORMAT = "[ERROR] Wrong file format. Viewer can show *.3dx or *.3d files only.",
  13.   ERROR_INVALID_FORMAT_STRUCTURE = "[ERROR] Invalid file structure.",
  14.   ERROR_UNABLE_TO_OPEN = "[ERROR] Cannot open: ",
  15.   ERROR_FILE_NOT_FOUND = "[ERROR] File not found: ",
  16.   ERROR_WRONG_SCALE = "[ERROR] Scale parameter must be a number between 0.33 and 4.00",
  17.   ERROR_NO_PROJECTOR = "[ERROR] Projector is not found.",
  18.   DONE = "Done. The hologram was successfully rendered."
  19. }
  20.  
  21. -- ================================ H O L O G R A M S   S T U F F ================================ --
  22. -- loading add. components
  23. function trytofind(name)
  24.   if com.isAvailable(name) then
  25.     return com.getPrimary(name)
  26.   else
  27.     return nil
  28.   end
  29. end
  30.  
  31. -- constants
  32. HOLOH = 32
  33. HOLOW = 48
  34.  
  35. -- hologram vars
  36. holo = {}
  37. colortable = {{},{},{}}
  38. hexcolortable = {}
  39. proj_scale = 1.0
  40.  
  41. function set(x, y, z, value)
  42.   if holo[x] == nil then holo[x] = {} end
  43.   if holo[x][y] == nil then holo[x][y] = {} end
  44.   holo[x][y][z] = value
  45. end
  46. function get(x, y, z)
  47.   if holo[x] ~= nil and holo[x][y] ~= nil and holo[x][y][z] ~= nil then
  48.     return holo[x][y][z]
  49.   else
  50.     return 0
  51.   end
  52. end
  53. function rgb2hex(r,g,b)
  54.   return r*65536+g*256+b
  55. end
  56.  
  57.  
  58. local reader = {}
  59. function reader:init(file)
  60.   self.buffer = {}
  61.   self.file = file
  62. end
  63. function reader:read()
  64.   if #self.buffer == 0 then
  65.     if not self:fetch() then return nil end
  66.   end
  67.   local sym = self.buffer[#self.buffer]
  68.   self.buffer[#self.buffer] = nil
  69.   return sym
  70. end
  71. function reader:fetch()
  72.   self.buffer = {}
  73.   local char = file:read(1)
  74.   if char == nil then return false
  75.   else
  76.     local byte = string.byte(char)
  77.     for i=0, 3 do
  78.       local a = byte % 4
  79.       byte = math.floor(byte / 4)
  80.       self.buffer[4-i] = a
  81.     end
  82.     return true
  83.   end
  84. end
  85.  
  86. local function loadHologram(filename)
  87.   if filename == nil then
  88.     error(loc.ERROR_NO_FILENAME)
  89.   end
  90.  
  91.   local path = shell.resolve(filename, "3dx")
  92.   if path == nil then path = shell.resolve(filename, "3d") end
  93.  
  94.   if path ~= nil then
  95.     local compressed
  96.     if string.sub(path, -4) == '.3dx' then
  97.       compressed = true
  98.     elseif string.sub(path, -3) == '.3d' then
  99.       compressed = false
  100.     else
  101.       error(loc.ERROR_WRONG_FILE_FORMAT)
  102.     end
  103.     file = io.open(path, 'rb')
  104.     if file ~= nil then
  105.       for i=1, 3 do
  106.         for c=1, 3 do
  107.           colortable[i][c] = string.byte(file:read(1))
  108.         end
  109.         hexcolortable[i] = rgb2hex(colortable[i][1], colortable[i][2], colortable[i][3])
  110.       end
  111.       holo = {}
  112.       reader:init(file)
  113.       if compressed then
  114.         local x, y, z = 1, 1, 1
  115.         while true do
  116.           local a = reader:read()
  117.           if a == nil then file:close(); return true end
  118.           local len = 1
  119.           while true do
  120.             local b = reader:read()
  121.             if b == nil then
  122.               file:close()
  123.               if a == 0 then return true
  124.               else error(loc.ERROR_INVALID_FORMAT_STRUCTURE) end
  125.             end
  126.             local fin = (b > 1)
  127.             if fin then b = b - 2 end
  128.             len = bit32.lshift(len, 1)
  129.             len = len + b
  130.             if fin then break end
  131.           end
  132.           len = len - 1
  133.           for i = 1, len do
  134.             if a ~= 0 then set(x,y,z, a) end
  135.             z = z + 1
  136.             if z > HOLOW then
  137.               y = y + 1
  138.               if y > HOLOH then
  139.                 x = x + 1
  140.                 if x > HOLOW then file:close(); return true end
  141.                 y = 1
  142.               end
  143.               z = 1
  144.             end  
  145.           end
  146.         end
  147.       else
  148.         for x = 1, HOLOW do
  149.           for y = 1, HOLOH do
  150.             for z = 1, HOLOW do
  151.               local a = reader:read()
  152.               if a ~= 0 and a ~= nil then
  153.                 set(x, y, z, a)
  154.               end
  155.             end
  156.           end
  157.         end
  158.       end
  159.       file:close()
  160.       return true
  161.     else
  162.       error(loc.ERROR_UNABLE_TO_OPEN .. filename)
  163.     end
  164.   else
  165.     error(loc.ERROR_FILE_NOT_FOUND .. filename)
  166.   end
  167. end
  168.  
  169. function scaleHologram(scale)
  170.   if scale == nil or scale < 0.33 or scale > 4 then
  171.     error(loc.ERROR_WRONG_SCALE)
  172.   end
  173.   proj_scale = scale
  174. end
  175.  
  176. function drawHologram()
  177.   -- check hologram projector availability
  178.   h = trytofind('hologram')
  179.   if h ~= nil then
  180.     local depth = h.maxDepth()
  181.     -- clear projector
  182.     h.clear()
  183.     -- set projector scale
  184.     h.setScale(proj_scale)
  185.     -- send palette
  186.     if depth == 2 then
  187.       for i = 1, 3 do
  188.         h.setPaletteColor(i, hexcolortable[i])
  189.       end
  190.     else
  191.       h.setPaletteColor(1, hexcolortable[1])
  192.     end
  193.     -- send voxel array
  194.     for x = 1, HOLOW do
  195.       for y = 1, HOLOH do
  196.         for z = 1, HOLOW do
  197.           n = get(x,y,z)
  198.           if n ~= 0 then
  199.             if depth == 2 then
  200.               h.set(x, y, z, n)
  201.             else
  202.               h.set(x, y, z, 1)
  203.             end
  204.           end
  205.         end
  206.       end      
  207.     end
  208.     print(loc.DONE)
  209.   else
  210.     error(loc.ERROR_NO_PROJECTOR)
  211.   end
  212. end
  213. -- =============================================================================================== --
  214.  
  215. -- Main part
  216. loadHologram(args[1])
  217.  
  218. if args[2] ~= nil then
  219.   scaleHologram(tonumber(args[2]))
  220. end
  221.  
  222. drawHologram()
RAW Paste Data