Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local utf8 = require'utf8'
- local display = {}
- display._white = {1, 1, 1, 1}
- display.__index = display
- local default_charset = {
- [[ ☺☻♥♦♣♠•◘○◙♂♀♪♫☼]],
- [[►◄↕‼¶§▬↨↑↓→←∟↔▲▼]],
- [[ !"#$%&'()*+,-./]],
- [[0123456789:;<=>?]],
- [[@ABCDEFGHIJKLMNO]],
- [[PQRSTUVWXYZ[\]^_]],
- [[`abcdefghijklmno]],
- [[pqrstuvwxyz{|}~⌂]],
- [[ÇüéâäàåçêëèïîìÄÅ]],
- [[ÉæÆôöòûùÿÖÜ¢£¥₧ƒ]],
- [[áíóúñѪº¿⌐¬½¼¡«»]],
- [[░▒▓│┤╡╢╖╕╣║╗╝╜╛┐]],
- [[└┴┬├─┼╞╟╚╔╩╦╠═╬╧]],
- [[╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀]],
- [[αßΓπΣσµτΦΘΩδ∞φε∩]],
- [[≡±≥≤⌠⌡÷≈°∙·√ⁿ²■⯑]]
- }
- function display:new(image, w, h, sym, def)
- sym = sym or default_charset
- local gr = love.graphics
- self = setmetatable({}, self)
- self.image = gr.newImage(image)
- self.map = {}
- self.layers = {}
- self.layer = nil -- current layer
- self.image:setFilter('nearest')
- local iw, ih = self.image:getDimensions()
- self.w = iw/w
- self.h = ih/h
- local symw = iw/self.w
- local i = 0
- for p, c in utf8.codes(sym) do
- local char = utf8.char(c)
- local x, y = i%symw, math.floor(i/symw)
- x, y = x * self.w, y * self.h
- local quad = gr.newQuad(x, y, self.w, self.h, iw, ih)
- self.map[char] = quad
- self.map[i] = quad
- i = i + 1
- end
- self._s = assert(self:getQuad(def or ' '))
- self._b = assert(self:getQuad(def or ' '))
- self._scolor = self._white
- self._bcolor = self._white
- self:setLayer(1)
- return self
- end
- function display:getQuad(sym)
- return self.map[sym] or self.map[#self.map - 1]
- end
- function display:getImage()
- return self.image
- end
- function display:setLayer(i)
- local l = self.layers[i]
- if not l then
- l = {}
- l.batch = love.graphics.newSpriteBatch(self.image)
- l.used = {}
- self.layers[i] = l
- end
- self.layer = l
- end
- function display:setColor(color, ...)
- if type(color) == 'table' then
- self._scolor = color
- return
- end
- if type(color) == 'number' then
- self._scolor = {color, ...}
- return
- end
- self._scolor = self._white
- end
- function display:setBackground(sym)
- self._b = assert(self:getQuad(sym))
- end
- function display:setBackgroundColor(color, ...)
- if type(color) == 'table' then
- self._bcolor = color
- return
- end
- if type(color) == 'number' then
- self._bcolor = {color, ...}
- return
- end
- self._bcolor = self._white
- end
- function display:draw(...)
- for i, v in pairs(self.layers) do
- love.graphics.draw(v.batch, ...)
- end
- end
- display.__call = display.get
- -- get index of instance in batch or create new
- function display:_batch_get_tile(x, y)
- local layer = self.layer
- if not layer.used[y] then
- layer.used[y] = {}
- end
- if not layer.used[y][x] then
- -- background, tile
- layer.batch:setColor(self._bcolor)
- local backgr = layer.batch:add(self._b, x * self.w, y * self.h)
- layer.batch:setColor(self._scolor)
- local foregr = layer.batch:add(self._s, x * self.w, y * self.h)
- -- tile struct: foregr index, backgr index, backgr quad, foregr quad
- layer.used[y][x] = {backgr, foregr, self._b, self._s}
- end
- return layer.used[y][x]
- end
- function display:set(foregr, x, y, foregr_color, backgr, backgr_color)
- local layer = self.layer
- local tile = self:_batch_get_tile(x, y)
- if foregr then
- foregr = self:getQuad(foregr)
- layer.batch:setColor(foregr_color or self._scolor)
- layer.batch:set(tile[2], foregr, x * self.w, y * self.h)
- end
- if backgr then
- backgr = self:getQuad(backgr)
- layer.batch:setColor(backgr_color or self._bcolor)
- layer.batch:set(tile[1], backgr, x * self.w, y * self.h)
- end
- end
- function display:clear(x, y, w, h, color)
- if x and y and w and h then
- local layer = self.layer
- for i = x, x + w - 1 do
- for j = y, y + h - 1 do
- local tile = self:_batch_get(i, j)
- -- background symbol
- layer.batch:setColor(color or self._scolor)
- layer.batch:set(tile[1], self._b, i * self.w, j * self.h)
- -- foreground symbol
- layer.batch:setColor(color or self._bcolor)
- layer.batch:set(tile[2], self._s, i * self.w, j * self.h)
- end
- end
- return
- end
- return self:clearLayer()
- end
- function display:getTile(x, y)
- local tile = self.layer.used
- return tile and trilemap[y][x]
- end
- function display:print(str, px, py)
- px = px or 0
- py = py or 0
- local x, y = 0, 0
- local bit = 4
- for p, c in utf8.codes(str) do
- c = utf8.char(c)
- if c == '\n' then
- x = 0
- y = y + 1
- else
- self:set(c, x + px, y + py)
- x = x + 1
- end
- end
- end
- function display:clearAll()
- for i, v in self.layers do
- v.batch:clear()
- v.used = {}
- end
- end
- function display:clearLayer(i)
- local l = self.layers[i] or self.layer
- if l then
- l.batch:clear()
- l.used = {}
- end
- end
- local bit = require'bit'
- local image = {}
- image.__index = image
- local bor = bit.bor
- local lshift = bit.lshift
- local function tonumber32(a, b, c, d)
- a, b, c, d = a or 0, b or 0, c or 0, d or 0
- b, c, d = lshift(b, 8), lshift(c, 16), lshift(d, 24)
- return bor(a, bor(b, bor(c, d)))
- end
- local function extract(data, a, b)
- return tonumber32(data:byte(a, b))
- end
- local function extractor(data)
- return function(a, b)
- return tonumber32(data:byte(a and a, b and b))
- end
- end
- local colorTable = {}
- local _colord = 1/255
- for i = 0, 255 do
- colorTable[i] = i * _colord
- end
- function colorTable:getColor(r, g, b)
- if self[r] then
- self[r] = r * _colord
- end
- if self[g] then
- self[g] = g * _colord
- end
- if self[b] then
- self[b] = b * _colord
- end
- return self[r], self[g], self[b]
- end
- function image:load(file, display)
- print('Load:', file)
- local data = love.filesystem.read(file)
- data = love.math.decompress(data, 'zlib')
- local ext = extractor(data)
- local self = setmetatable({}, self)
- self.data = data
- self.version = ext(1, 4)
- self.layers = ext(5, 8)
- self.width = ext(9, 12)
- self.height = ext(13, 16)
- self.boffset = 17
- self.btilew = 10
- print('w/h: ', self.version, self.layers, self.width, self.height)
- local char = ext(17, 20)
- local r1, g1, b1, r2, g2, b2 = data:byte(21, 26)
- print('first char', char, r1, g1, b1, r2, g2, b2)
- return self
- end
- function display:render(image, x, y)
- x = x or 0
- y = y or 0
- local w = image.width - 1
- local h = image.height - 1
- local b = image.boffset
- local data = image.data
- local fcolor, bcolor = {}, {}
- local b = 7
- local px, py = 0, 0
- for i = 1, image.width * image.height do
- b = b + 10
- local data = data:sub(b, b + 10)
- local char = extract(data, 1, 4)
- local r1, g1, b1 = data:byte(5, 7)
- local r2, g2, b2 = data:byte(8, 10)
- fcolor[1], fcolor[2], fcolor[3] = colorTable:getColor(r1, g1, b1)
- bcolor[1], bcolor[2], bcolor[3] = colorTable:getColor(r2, g2, b2)
- self:set(char, x + px, y + py, fcolor, '█', bcolor)
- py = py + 1
- if py >= image.height then
- py = 0
- px = px + 1
- end
- end
- end
- function image:getTile(x, y, layer)
- layer = layer and layer - 1 or 0
- x = x - 1
- y = y - 1
- local w = self.width - 1
- local h = self.height - 1
- local b = self.boffset + y * w + x + (layer * w * h)
- local char = extract(self.data, b, b + 3)
- local r1, g1, b1, r2, g2, b2, b3, b4 = self.data:byte(b + 4, b + 9)
- print('start byte:', b, b + 4, b + 5, b + 10, '::', char, r1, g1, b1, r2, g2, b2, b3, b4)
- r1, g1, b1 = colorTable:getColor(r1, g1, b1)
- r2, g2, b2 = colorTable:getColor(r2, g2, b2)
- return char, r1, g1, b1, r2, g2, b2
- end
- function display:newImage(file)
- return image:load(file, self)
- end
- return display
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement