MiraMiraMira

CTIF Viewer

Feb 15th, 2020
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.58 KB | None | 0 0
  1. local args = {...}
  2. local component = require("component")
  3. local event = require("event")
  4. local gpu = component.gpu
  5. local unicode = require("unicode")
  6. local keyboard = require("keyboard")
  7. local text = require("text")
  8. local os = require("os")
  9. local pal = {}
  10.  
  11. local q = {}
  12. for i=0,255 do
  13.   local dat = (i & 0x01) << 7
  14.   dat = dat | (i & 0x02) >> 1 << 6
  15.   dat = dat | (i & 0x04) >> 2 << 5
  16.   dat = dat | (i & 0x08) >> 3 << 2
  17.   dat = dat | (i & 0x10) >> 4 << 4
  18.   dat = dat | (i & 0x20) >> 5 << 1
  19.   dat = dat | (i & 0x40) >> 6 << 3
  20.   dat = dat | (i & 0x80) >> 7
  21.   q[i + 1] = unicode.char(0x2800 | dat)
  22. end
  23.  
  24. function error(str)
  25.   print("ERROR: " .. str)
  26.   os.exit()
  27. end
  28.  
  29. function resetPalette(data)
  30.  for i=0,255 do
  31.   if (i < 16) then
  32.     if data == nil or data[3] == nil or data[3][i] == nil then
  33.       pal[i] = (i * 15) << 16 | (i * 15) << 8 | (i * 15)
  34.     else
  35.       pal[i] = data[3][i]
  36.       gpu.setPaletteColor(i, data[3][i])
  37.     end
  38.   else
  39.     local j = i - 16
  40.     local b = math.floor((j % 5) * 255 / 4.0)
  41.     local g = math.floor((math.floor(j / 5.0) % 8) * 255 / 7.0)
  42.     local r = math.floor((math.floor(j / 40.0) % 6) * 255 / 5.0)
  43.     pal[i] = r << 16 | g << 8 | b
  44.   end
  45.  end
  46. end
  47.  
  48. resetPalette(nil)
  49.  
  50. function r8(file)
  51.   local byte = file:read(1)
  52.   if byte == nil then
  53.     return 0
  54.   else
  55.     return string.byte(byte) & 255
  56.   end
  57. end
  58.  
  59. function r16(file)
  60.   local x = r8(file)
  61.   return x | (r8(file) << 8)
  62. end
  63.  
  64. function loadImage(filename)
  65.   local data = {}
  66.   local file = io.open(filename, 'rb')
  67.   local hdr = {67,84,73,70}
  68.  
  69.   for i=1,4 do
  70.     if r8(file) ~= hdr[i] then
  71.       error("Invalid header!")
  72.     end
  73.   end
  74.  
  75.   local hdrVersion = r8(file)
  76.   local platformVariant = r8(file)
  77.   local platformId = r16(file)
  78.  
  79.   if hdrVersion > 1 then
  80.     error("Unknown header version: " .. hdrVersion)
  81.   end
  82.  
  83.   if platformId ~= 1 or platformVariant ~= 0 then
  84.     error("Unsupported platform ID: " .. platformId .. ":" .. platformVariant)
  85.   end
  86.  
  87.   data[1] = {}
  88.   data[2] = {}
  89.   data[3] = {}
  90.   data[2][1] = r8(file)
  91.   data[2][1] = (data[2][1] | (r8(file) << 8))
  92.   data[2][2] = r8(file)
  93.   data[2][2] = (data[2][2] | (r8(file) << 8))
  94.  
  95.   local pw = r8(file)
  96.   local ph = r8(file)
  97.   if not (pw == 2 and ph == 4) then
  98.     error("Unsupported character width: " .. pw .. "x" .. ph)
  99.   end
  100.  
  101.   data[2][3] = r8(file)
  102.   if (data[2][3] ~= 4 and data[2][3] ~= 8) or data[2][3] > gpu.getDepth() then
  103.     error("Unsupported bit depth: " .. data[2][3])
  104.   end
  105.  
  106.   local ccEntrySize = r8(file)
  107.   local customColors = r16(file)
  108.   if customColors > 0 and ccEntrySize ~= 3 then
  109.     error("Unsupported palette entry size: " .. ccEntrySize)
  110.   end
  111.   if customColors > 16 then
  112.     error("Unsupported palette entry amount: " .. customColors)
  113.   end
  114.  
  115.   for p=0,customColors-1 do
  116.     local w = r16(file)
  117.     data[3][p] = w | (r8(file) << 16)
  118.   end
  119.  
  120.   local WIDTH = data[2][1]
  121.   local HEIGHT = data[2][2]
  122.  
  123.   for y=0,HEIGHT-1 do
  124.     for x=0,WIDTH-1 do
  125.       local j = (y * WIDTH) + x + 1
  126.       local w = r16(file)
  127.       if data[2][3] > 4 then
  128.         data[1][j] = w | (r8(file) << 16)
  129.       else
  130.         data[1][j] = w
  131.       end
  132.     end
  133.   end
  134.  
  135.   io.close(file)
  136.   return data
  137. end
  138.  
  139. function gpuBG()
  140.   local a, al = gpu.getBackground()
  141.   if al then
  142.     return gpu.getPaletteColor(a)
  143.   else
  144.     return a
  145.   end
  146. end
  147. function gpuFG()
  148.   local a, al = gpu.getForeground()
  149.   if al then
  150.     return gpu.getPaletteColor(a)
  151.   else
  152.     return a
  153.   end
  154. end
  155.  
  156. function drawImage(data, offx, offy)
  157.   if offx == nil then offx = 0 end
  158.   if offy == nil then offy = 0 end
  159.  
  160.   local WIDTH = data[2][1]
  161.   local HEIGHT = data[2][2]
  162.  
  163.   gpu.setResolution(WIDTH, HEIGHT)
  164.   resetPalette(data)
  165.  
  166.   local bg = 0
  167.   local fg = 0
  168.   local cw = 1
  169.   local noBG = false
  170.   local noFG = false
  171.   local ind = 1
  172.  
  173.   local gBG = gpuBG()
  174.   local gFG = gpuFG()
  175.  
  176.   for y=0,HEIGHT-1 do
  177.     local str = ""
  178.     for x=0,WIDTH-1 do
  179.       ind = (y * WIDTH) + x + 1
  180.       if data[2][3] > 4 then
  181.         bg = pal[data[1][ind] & 0xFF]
  182.         fg = pal[(data[1][ind] >> 8) & 0xFF]
  183.         cw = ((data[1][ind] >> 16) & 0xFF) + 1
  184.       else
  185.         fg = pal[data[1][ind] & 0x0F]
  186.         bg = pal[(data[1][ind] >> 4) & 0x0F]
  187.         cw = ((data[1][ind] >> 8) & 0xFF) + 1
  188.       end
  189.       noBG = (cw == 256)
  190.       noFG = (cw == 1)
  191.       if (noFG or (gBG == fg)) and (noBG or (gFG == bg)) then
  192.         str = str .. q[257 - cw]
  193. --        str = str .. "I"
  194.       elseif (noBG or (gBG == bg)) and (noFG or (gFG == fg)) then
  195.         str = str .. q[cw]
  196.       else
  197.         if #str > 0 then
  198.           gpu.set(x + 1 + offx - unicode.wlen(str), y + 1 + offy, str)
  199.         end
  200.         if (gBG == fg and gFG ~= bg) or (gFG == bg and gBG ~= fg) then
  201.           cw = 257 - cw
  202.           local t = bg
  203.           bg = fg
  204.           fg = t
  205.         end
  206.         if gBG ~= bg then
  207.           gpu.setBackground(bg)
  208.           gBG = bg
  209.         end
  210.         if gFG ~= fg then
  211.           gpu.setForeground(fg)
  212.           gFG = fg
  213.         end
  214.         str = q[cw]
  215. --        if (not noBG) and (not noFG) then str = "C" elseif (not noBG) then str = "B" elseif (not noFG) then str = "F" else str = "c" end
  216.       end
  217.     end
  218.     if #str > 0 then
  219.       gpu.set(WIDTH + 1 - unicode.wlen(str) + offx, y + 1 + offy, str)
  220.     end
  221.   end
  222. end
  223.  
  224. local image = loadImage(args[1])
  225. drawImage(image)
  226.  
  227. while true do
  228.     local name,addr,char,key,player = event.pull("key_down")
  229.     if key == 0x10 then
  230.         break
  231.     end
  232. end
  233.  
  234. gpu.setBackground(0, false)
  235. gpu.setForeground(16777215, false)
  236. gpu.setResolution(80, 25)
  237. gpu.fill(1, 1, 80, 25, " ")
Add Comment
Please, Sign In to add comment