Advertisement
Snusmumriken

Love2d rexpaint display

Jan 12th, 2019
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.65 KB | None | 0 0
  1. local utf8  = require'utf8'
  2. local display = {}
  3. display._white = {1, 1, 1, 1}
  4. display.__index = display
  5.  
  6.  
  7. local default_charset = {
  8.     [[ ☺☻♥♦♣♠•◘○◙♂♀♪♫☼]],
  9.     [[►◄↕‼¶§▬↨↑↓→←∟↔▲▼]],
  10.     [[ !"#$%&'()*+,-./]],
  11.     [[0123456789:;<=>?]],
  12.     [[@ABCDEFGHIJKLMNO]],
  13.     [[PQRSTUVWXYZ[\]^_]],
  14.     [[`abcdefghijklmno]],
  15.     [[pqrstuvwxyz{|}~⌂]],
  16.     [[ÇüéâäàåçêëèïîìÄÅ]],
  17.     [[ÉæÆôöòûùÿÖÜ¢£¥₧ƒ]],
  18.     [[áíóúñѪº¿⌐¬½¼¡«»]],
  19.     [[░▒▓│┤╡╢╖╕╣║╗╝╜╛┐]],
  20.     [[└┴┬├─┼╞╟╚╔╩╦╠═╬╧]],
  21.     [[╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀]],
  22.     [[αßΓπΣσµτΦΘΩδ∞φε∩]],
  23.     [[≡±≥≤⌠⌡÷≈°∙·√ⁿ²■⯑]]
  24. }
  25.  
  26. function display:new(image, w, h, sym, def)
  27.     sym = sym or default_charset
  28.  
  29.     local gr   = love.graphics
  30.     self         = setmetatable({}, self)
  31.     self.image   = gr.newImage(image)
  32.     self.map     = {}
  33.     self.layers  = {}
  34.     self.layer = nil -- current layer
  35.    
  36.     self.image:setFilter('nearest')
  37.    
  38.     local iw, ih = self.image:getDimensions()
  39.     self.w     = iw/w
  40.     self.h     = ih/h
  41.    
  42.     local symw   = iw/self.w
  43.    
  44.     local i = 0
  45.     for p, c in utf8.codes(sym) do
  46.         local char = utf8.char(c)
  47.         local x, y = i%symw, math.floor(i/symw)
  48.         x, y = x * self.w, y * self.h
  49.         local quad = gr.newQuad(x, y, self.w, self.h, iw, ih)
  50.         self.map[char] = quad
  51.         self.map[i]    = quad
  52.         i = i + 1
  53.     end
  54.    
  55.     self._s = assert(self:getQuad(def or ' '))
  56.     self._b = assert(self:getQuad(def or ' '))
  57.    
  58.     self._scolor = self._white
  59.     self._bcolor = self._white
  60.    
  61.     self:setLayer(1)
  62.     return self
  63. end
  64.  
  65. function display:getQuad(sym)
  66.     return self.map[sym] or self.map[#self.map - 1]
  67. end
  68.  
  69. function display:getImage()
  70.     return self.image
  71. end
  72.  
  73. function display:setLayer(i)
  74.     local l = self.layers[i]
  75.     if not l then
  76.         l = {}
  77.         l.batch = love.graphics.newSpriteBatch(self.image)
  78.         l.used  = {}
  79.         self.layers[i] = l
  80.     end
  81.     self.layer = l
  82. end
  83.  
  84. function display:setColor(color, ...)
  85.     if type(color) == 'table' then
  86.         self._scolor = color
  87.         return
  88.     end
  89.     if type(color) == 'number' then
  90.         self._scolor = {color, ...}
  91.         return
  92.     end
  93.     self._scolor = self._white
  94. end
  95.  
  96. function display:setBackground(sym)
  97.     self._b = assert(self:getQuad(sym))
  98. end
  99.  
  100. function display:setBackgroundColor(color, ...)
  101.     if type(color) == 'table' then
  102.         self._bcolor = color
  103.         return
  104.     end
  105.     if type(color) == 'number' then
  106.         self._bcolor = {color, ...}
  107.         return
  108.     end
  109.     self._bcolor = self._white
  110. end
  111.  
  112. function display:draw(...)
  113.     for i, v in pairs(self.layers) do
  114.         love.graphics.draw(v.batch, ...)
  115.     end
  116. end
  117.  
  118. display.__call = display.get
  119.  
  120. -- get index of instance in batch or create new
  121. function display:_batch_get_tile(x, y)
  122.     local layer = self.layer
  123.     if not layer.used[y] then
  124.         layer.used[y] = {}
  125.     end
  126.     if not layer.used[y][x] then
  127.         -- background, tile
  128.         layer.batch:setColor(self._bcolor)
  129.         local backgr = layer.batch:add(self._b, x * self.w, y * self.h)
  130.         layer.batch:setColor(self._scolor)
  131.         local foregr = layer.batch:add(self._s, x * self.w, y * self.h)
  132.        
  133.         -- tile struct: foregr index, backgr index, backgr quad, foregr quad
  134.         layer.used[y][x] = {backgr, foregr, self._b, self._s}
  135.     end
  136.    
  137.     return layer.used[y][x]
  138. end
  139.  
  140. function display:set(foregr, x, y, foregr_color, backgr, backgr_color)
  141.     local layer = self.layer
  142.     local tile  = self:_batch_get_tile(x, y)
  143.    
  144.     if foregr then
  145.         foregr = self:getQuad(foregr)
  146.         layer.batch:setColor(foregr_color or self._scolor)
  147.         layer.batch:set(tile[2], foregr, x * self.w, y * self.h)
  148.     end
  149.  
  150.     if backgr then
  151.         backgr = self:getQuad(backgr)
  152.         layer.batch:setColor(backgr_color or self._bcolor)
  153.         layer.batch:set(tile[1], backgr, x * self.w, y * self.h)
  154.     end
  155. end
  156.  
  157. function display:clear(x, y, w, h, color)
  158.     if x and y and w and h then
  159.         local layer = self.layer
  160.         for i = x, x + w - 1 do
  161.             for j = y, y + h - 1 do
  162.                 local tile = self:_batch_get(i, j)
  163.                 -- background symbol
  164.                 layer.batch:setColor(color or self._scolor)
  165.                 layer.batch:set(tile[1], self._b, i * self.w, j * self.h)
  166.                 -- foreground symbol
  167.                 layer.batch:setColor(color or self._bcolor)
  168.                 layer.batch:set(tile[2], self._s, i * self.w, j * self.h)
  169.             end
  170.         end
  171.         return
  172.     end
  173.    
  174.     return self:clearLayer()
  175. end
  176.  
  177. function display:getTile(x, y)
  178.     local tile = self.layer.used
  179.     return tile and trilemap[y][x]
  180. end
  181.  
  182. function display:print(str, px, py)
  183.     px = px or 0
  184.     py = py or 0
  185.     local x, y = 0, 0
  186.     local bit = 4
  187.     for p, c in utf8.codes(str) do
  188.         c = utf8.char(c)
  189.         if c == '\n' then
  190.             x = 0
  191.             y = y + 1
  192.         else
  193.             self:set(c, x + px, y + py)
  194.             x = x + 1
  195.         end
  196.     end
  197. end
  198.  
  199. function display:clearAll()
  200.     for i, v in self.layers do
  201.         v.batch:clear()
  202.         v.used = {}
  203.     end
  204. end
  205.  
  206. function display:clearLayer(i)
  207.     local l = self.layers[i] or self.layer
  208.     if l then
  209.         l.batch:clear()
  210.         l.used = {}
  211.     end
  212. end
  213.  
  214. local bit = require'bit'
  215. local image = {}
  216. image.__index = image
  217.  
  218. local bor    = bit.bor
  219. local lshift = bit.lshift
  220. local function tonumber32(a, b, c, d)
  221.     a, b, c, d = a or 0, b or 0, c or 0, d or 0
  222.     b, c, d = lshift(b, 8), lshift(c, 16), lshift(d, 24)
  223.     return bor(a, bor(b, bor(c, d)))
  224. end
  225.  
  226. local function extract(data, a, b)
  227.     return tonumber32(data:byte(a, b))
  228. end
  229.  
  230. local function extractor(data)
  231.     return function(a, b)
  232.         return tonumber32(data:byte(a and a, b and b))
  233.     end
  234. end
  235.  
  236. local colorTable = {}
  237. local _colord = 1/255
  238. for i = 0, 255 do
  239.     colorTable[i] = i * _colord
  240. end
  241.  
  242. function colorTable:getColor(r, g, b)
  243.     if self[r] then
  244.         self[r] = r * _colord
  245.     end
  246.     if self[g] then
  247.         self[g] = g * _colord
  248.     end
  249.     if self[b] then
  250.         self[b] = b * _colord
  251.     end
  252.     return self[r], self[g], self[b]
  253. end
  254.  
  255. function image:load(file, display)
  256.     print('Load:', file)
  257.     local data = love.filesystem.read(file)
  258.     data = love.math.decompress(data, 'zlib')
  259.     local ext = extractor(data)
  260.    
  261.    
  262.     local self = setmetatable({}, self)
  263.     self.data    = data
  264.     self.version = ext(1, 4)
  265.     self.layers  = ext(5, 8)
  266.     self.width   = ext(9, 12)
  267.     self.height  = ext(13, 16)
  268.     self.boffset = 17
  269.     self.btilew  = 10
  270.     print('w/h: ', self.version, self.layers, self.width, self.height)
  271.  
  272.     local char = ext(17, 20)
  273.     local r1, g1, b1, r2, g2, b2 = data:byte(21, 26)
  274.    
  275.     print('first char', char, r1, g1, b1, r2, g2, b2)
  276.  
  277.     return self
  278. end
  279.  
  280. function display:render(image, x, y)
  281.     x = x or 0
  282.     y = y or 0
  283.     local w = image.width  - 1
  284.     local h = image.height - 1
  285.     local b = image.boffset
  286.     local data = image.data
  287.     local fcolor, bcolor = {}, {}
  288.    
  289.     local b = 7
  290.    
  291.     local px, py = 0, 0
  292.     for i = 1, image.width * image.height do
  293.         b = b + 10
  294.         local data = data:sub(b, b + 10)
  295.         local char = extract(data, 1, 4)
  296.        
  297.         local r1, g1, b1 = data:byte(5, 7)
  298.         local r2, g2, b2 = data:byte(8, 10)
  299.        
  300.         fcolor[1], fcolor[2], fcolor[3] = colorTable:getColor(r1, g1, b1)
  301.         bcolor[1], bcolor[2], bcolor[3] = colorTable:getColor(r2, g2, b2)
  302.        
  303.         self:set(char, x + px, y + py, fcolor, '█', bcolor)
  304.        
  305.         py = py + 1
  306.         if py >= image.height then
  307.             py = 0
  308.             px = px + 1
  309.         end
  310.     end
  311. end
  312.  
  313.  
  314. function image:getTile(x, y, layer)
  315.     layer = layer and layer - 1 or 0
  316.     x = x - 1
  317.     y = y - 1
  318.    
  319.     local w = self.width  - 1
  320.     local h = self.height - 1
  321.     local b = self.boffset + y * w + x + (layer * w * h)
  322.    
  323.     local char = extract(self.data, b, b + 3)
  324.     local r1, g1, b1, r2, g2, b2, b3, b4 = self.data:byte(b + 4, b + 9)
  325.     print('start byte:', b, b + 4, b + 5, b + 10, '::', char, r1, g1, b1, r2, g2, b2, b3, b4)
  326.    
  327.     r1, g1, b1 = colorTable:getColor(r1, g1, b1)
  328.     r2, g2, b2 = colorTable:getColor(r2, g2, b2)
  329.     return char, r1, g1, b1, r2, g2, b2
  330. end
  331.  
  332.  
  333. function display:newImage(file)
  334.     return image:load(file, self)
  335. end
  336.  
  337.  
  338. return display
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement