Advertisement
BubbleGum4ik

Untitled

Jul 1st, 2024
659
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.44 KB | Source Code | 0 0
  1. local pixelbox = {}
  2. local box_object = {}
  3. local t_cat  = table.concat
  4. local sampling_lookup = {
  5.     {2,3,4,5,6},
  6.     {4,1,6,3,5},
  7.     {1,4,5,2,6},
  8.     {2,6,3,5,1},
  9.     {3,6,1,4,2},
  10.     {4,5,2,3,1}
  11. }
  12. local texel_character_lookup  = {}
  13. local texel_foreground_lookup = {}
  14. local texel_background_lookup = {}
  15. local to_blit = {}
  16. local function generate_identifier(s1,s2,s3,s4,s5,s6)
  17.     return  s2 * 1 +
  18.             s3 * 3 +
  19.             s4 * 4 +
  20.             s5 * 20 +
  21.             s6 * 100
  22. end
  23. local function calculate_texel(v1,v2,v3,v4,v5,v6)
  24.     local texel_data = {v1,v2,v3,v4,v5,v6}
  25.     local state_lookup = {}
  26.     for i=1,6 do
  27.         local subpixel_state = texel_data[i]
  28.         local current_count = state_lookup[subpixel_state]
  29.         state_lookup[subpixel_state] = current_count and current_count + 1 or 1
  30.     end
  31.     local sortable_states = {}
  32.     for k,v in pairs(state_lookup) do
  33.         sortable_states[#sortable_states+1] = {
  34.             value = k,
  35.             count = v
  36.         }
  37.     end
  38.     table.sort(sortable_states,function(a,b)
  39.         return a.count > b.count
  40.     end)
  41.     local texel_stream = {}
  42.     for i=1,6 do
  43.         local subpixel_state = texel_data[i]
  44.         if subpixel_state == sortable_states[1].value then
  45.             texel_stream[i] = 1
  46.         elseif subpixel_state == sortable_states[2].value then
  47.             texel_stream[i] = 0
  48.         else
  49.             local sample_points = sampling_lookup[i]
  50.             for sample_index=1,5 do
  51.                 local sample_subpixel_index = sample_points[sample_index]
  52.                 local sample_state          = texel_data   [sample_subpixel_index]
  53.                 local common_state_1 = sample_state == sortable_states[1].value
  54.                 local common_state_2 = sample_state == sortable_states[2].value
  55.                 if common_state_1 or common_state_2 then
  56.                     texel_stream[i] = common_state_1 and 1 or 0
  57.                     break
  58.                 end
  59.             end
  60.         end
  61.     end
  62.     local char_num = 128
  63.     local stream_6 = texel_stream[6]
  64.     if texel_stream[1] ~= stream_6 then char_num = char_num + 1  end
  65.     if texel_stream[2] ~= stream_6 then char_num = char_num + 2  end
  66.     if texel_stream[3] ~= stream_6 then char_num = char_num + 4  end
  67.     if texel_stream[4] ~= stream_6 then char_num = char_num + 8  end
  68.     if texel_stream[5] ~= stream_6 then char_num = char_num + 16 end
  69.     local state_1,state_2
  70.     if #sortable_states > 1 then
  71.         state_1 = sortable_states[  stream_6+1].value
  72.         state_2 = sortable_states[2-stream_6  ].value
  73.     else
  74.         state_1 = sortable_states[1].value
  75.         state_2 = sortable_states[1].value
  76.     end
  77.     return char_num,state_1,state_2
  78. end
  79. local function base_n_rshift(n,base,shift)
  80.     return math.floor(n/(base^shift))
  81. end
  82. local real_entries = 0
  83. local function generate_lookups()
  84.     for i = 0, 15 do
  85.         to_blit[2^i] = ("%x"):format(i)
  86.     end
  87.     for encoded_pattern=0,6^6 do
  88.         local subtexel_1 = base_n_rshift(encoded_pattern,6,0) % 6
  89.         local subtexel_2 = base_n_rshift(encoded_pattern,6,1) % 6
  90.         local subtexel_3 = base_n_rshift(encoded_pattern,6,2) % 6
  91.         local subtexel_4 = base_n_rshift(encoded_pattern,6,3) % 6
  92.         local subtexel_5 = base_n_rshift(encoded_pattern,6,4) % 6
  93.         local subtexel_6 = base_n_rshift(encoded_pattern,6,5) % 6
  94.         local pattern_lookup = {}
  95.         pattern_lookup[subtexel_6] = 5
  96.         pattern_lookup[subtexel_5] = 4
  97.         pattern_lookup[subtexel_4] = 3
  98.         pattern_lookup[subtexel_3] = 2
  99.         pattern_lookup[subtexel_2] = 1
  100.         pattern_lookup[subtexel_1] = 0
  101.         local pattern_identifier = generate_identifier(
  102.             pattern_lookup[subtexel_1],pattern_lookup[subtexel_2],
  103.             pattern_lookup[subtexel_3],pattern_lookup[subtexel_4],
  104.             pattern_lookup[subtexel_5],pattern_lookup[subtexel_6]
  105.         )
  106.         if not texel_character_lookup[pattern_identifier] then
  107.             real_entries = real_entries + 1
  108.             local character,sub_state_1,sub_state_2 = calculate_texel(
  109.                 subtexel_1,subtexel_2,
  110.                 subtexel_3,subtexel_4,
  111.                 subtexel_5,subtexel_6
  112.             )
  113.             local color_1_location = pattern_lookup[sub_state_1] + 1
  114.             local color_2_location = pattern_lookup[sub_state_2] + 1
  115.             texel_foreground_lookup[pattern_identifier] = color_1_location
  116.             texel_background_lookup[pattern_identifier] = color_2_location
  117.             texel_character_lookup[pattern_identifier] = string.char(character)
  118.         end
  119.     end
  120. end
  121. function pixelbox.restore(box,color,keep_existing)
  122.     if not keep_existing then
  123.         local new_canvas = {}
  124.         for y=1,box.height do
  125.             for x=1,box.width do
  126.                 if not new_canvas[y] then new_canvas[y] = {} end
  127.                 new_canvas[y][x] = color
  128.             end
  129.         end
  130.         box.canvas = new_canvas
  131.         box.CANVAS = new_canvas
  132.     else
  133.         local canvas = box.canvas
  134.         for y=1,box.height do
  135.             for x=1,box.width do
  136.                 if not bc[y] then bc[y] = {} end
  137.                 if not canvas[y][x] then
  138.                     canvas[y][x] = color
  139.                 end
  140.             end
  141.         end
  142.     end
  143. end
  144. local color_lookup  = {}
  145. local texel_body    = {0,0,0,0,0,0}
  146. function box_object:render()
  147.     local t = self.term
  148.     local blit_line,set_cursor = t.blit,t.setCursorPos
  149.     local canv = self.canvas
  150.     local char_line,fg_line,bg_line = {},{},{}
  151.     local width,height = self.width,self.height
  152.     local sy = 0
  153.     for y=1,height,3 do
  154.         sy = sy + 1
  155.         local layer_1 = canv[y]
  156.         local layer_2 = canv[y+1]
  157.         local layer_3 = canv[y+2]
  158.         local n = 0
  159.         for x=1,width,2 do
  160.             local xp1 = x+1
  161.             local b1,b2,b3,b4,b5,b6 =
  162.                 layer_1[x],layer_1[xp1],
  163.                 layer_2[x],layer_2[xp1],
  164.                 layer_3[x],layer_3[xp1]
  165.             local char,fg,bg = " ",1,b1
  166.             local single_color = b2 == b1
  167.                             and  b3 == b1
  168.                             and  b4 == b1
  169.                             and  b5 == b1
  170.                             and  b6 == b1
  171.             if not single_color then
  172.                 color_lookup[b6] = 5
  173.                 color_lookup[b5] = 4
  174.                 color_lookup[b4] = 3
  175.                 color_lookup[b3] = 2
  176.                 color_lookup[b2] = 1
  177.                 color_lookup[b1] = 0
  178.                 local pattern_identifier =
  179.                     color_lookup[b2]       +
  180.                     color_lookup[b3] * 3   +
  181.                     color_lookup[b4] * 4   +
  182.                     color_lookup[b5] * 20  +
  183.                     color_lookup[b6] * 100
  184.                 local fg_location = texel_foreground_lookup[pattern_identifier]
  185.                 local bg_location = texel_background_lookup[pattern_identifier]
  186.                 texel_body[1] = b1
  187.                 texel_body[2] = b2
  188.                 texel_body[3] = b3
  189.                 texel_body[4] = b4
  190.                 texel_body[5] = b5
  191.                 texel_body[6] = b6
  192.                 fg = texel_body[fg_location]
  193.                 bg = texel_body[bg_location]
  194.                 char = texel_character_lookup[pattern_identifier]
  195.             end
  196.             n = n + 1
  197.             char_line[n] = char
  198.             fg_line  [n] = to_blit[fg]
  199.             bg_line  [n] = to_blit[bg]
  200.         end
  201.         set_cursor(1,sy)
  202.         blit_line(
  203.             t_cat(char_line,""),
  204.             t_cat(fg_line,  ""),
  205.             t_cat(bg_line,  "")
  206.         )
  207.     end
  208. end
  209. function box_object:clear(color)
  210.     pixelbox.restore(self,color)
  211. end
  212. function box_object:set_pixel(x,y,color)
  213.     self.canvas[y][x] = color
  214. end
  215. function box_object:resize(w,h,color)
  216.     self.term_width  = w
  217.     self.term_height = h
  218.     self.width  = w*2
  219.     self.height = h*3
  220.     pixelbox.restore(self,color or self.background,true)
  221. end
  222. local first_run = true
  223. function pixelbox.new(terminal,bg)
  224.     local box = {}
  225.     box.background = bg or terminal.getBackgroundColor() or colors.black
  226.     local w,h = terminal.getSize()
  227.     box.term  = terminal
  228.     setmetatable(box,{__index = box_object})
  229.     box.term_width  = w
  230.     box.term_height = h
  231.     box.width       = w*2
  232.     box.height      = h*3
  233.     pixelbox.restore(box,box.background)
  234.     if first_run then
  235.         generate_lookups()
  236.         first_run = false
  237.     end
  238.     return box
  239. end
  240. return pixelbox
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement