From 80bf27f647f587a5175f7b68bfe7dd4a7da17f5c Mon Sep 17 00:00:00 2001 From: Pixel Date: Tue, 5 Jan 2010 08:52:26 -0800 Subject: Framebuffer almost done; zoom is slightly broken. --- dalos-framebuffer.lua | 236 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 214 insertions(+), 22 deletions(-) diff --git a/dalos-framebuffer.lua b/dalos-framebuffer.lua index c21a193..f2dd01d 100644 --- a/dalos-framebuffer.lua +++ b/dalos-framebuffer.lua @@ -2,7 +2,16 @@ load "iupe-dbuffer.lua" dalosp.framebuffer = { get_settings = function (self) - return { width = self.extra.width, height = self.extra.height, bpp = self.extra.bpp } + local extra = self.extra + return { + width = extra.width, + height = extra.height, + bpp = extra.bpp, + zoom = extra.zoom, + ppdir = extra.ppdir, + flipx = extra.flipx, + flipy = extra.flipy, + } end, input_change = function (self, ind) @@ -11,13 +20,19 @@ dalosp.framebuffer = { if h then local cfg, s = h:readfile() s, cfg = pcall(loadstring, "local cfg = " .. cfg .. "\nreturn cfg\n") - if s then self:apply_config(cfg) end + if s then + self:apply_config(cfg) + self.extra.fb:prepare() + self.extra.fb:draw() + end end return end if h then h.getnextbyte = dalosp.framebuffer.getnextbyte end self:apply_config{} + self.extra.fb:prepare() + self.extra.fb:draw() end, activate = function (self) @@ -25,6 +40,7 @@ dalosp.framebuffer = { end, configure = function (self) + local extra = self.extra invert_lookup = { [1] = 0, [2] = 1, @@ -41,7 +57,7 @@ dalosp.framebuffer = { [4] = 24, [5] = 32, } - local owidth, oheight, obpp, oppdir = self.extra.width, self.extra.height, self.extra.bpp, self.extra.ppdir + local owidth, oheight, obpp, oppdir, oflipx, oflipy = extra.width, extra.height, extra.bpp, extra.ppdir, not not extra.flipx, not not extra.flipy local cb = function (dlg, pi) if pi < 0 then return end local width, height, bpp, dir @@ -49,27 +65,69 @@ dalosp.framebuffer = { height = iup.GetParamParam(dlg, 2).value + 0 bpp = iup.GetParamParam(dlg, 3).value + 0 dir = iup.GetParamParam(dlg, 4).value + 0 - self:apply_config{ width = width, height = height, bpp = lookup[bpp], dir = dir } + flipx = (iup.GetParamParam(dlg, 5).value + 0) ~= 0 + flipy = (iup.GetParamParam(dlg, 6).value + 0) ~= 0 + self:apply_config{ width = width, height = height, bpp = lookup[bpp], dir = dir, flipx = flipx, flipy = flipy } + self.extra.fb:prepare() + self.extra.fb:draw() end - local s, nname, width, height, bpp, ppdir = iup.GetParam(self.name .. " configuration", cb, "New name: %s\nWidth: %i\nHeight: %i\nBpp: %l|1 bpp|2 bpp|4 bpp|8 bpp|24 bpp|32 bpp|\nDirection: %l|Little Endian|Big Endian|\n", self.name, self.extra.width, self.extra.height, invert_lookup[self.extra.bpp], self.extra.ppdir) + local s, nname = iup.GetParam(self.name .. " configuration", cb, [[ +New name: %s +Width: %i +Height: %i +Bpp: %l|1 bpp|2 bpp|4 bpp|8 bpp|24 bpp|32 bpp| +Packed Pixels: %l|Little Endian|Big Endian| +Flip X axis: %b +Flip Y axis: %b +]], self.name, owidth, oheight, invert_lookup[obpp], oppdir, oflipx and 1 or 0, oflipy and 1 or 0) if not s then - self:apply_config{ width = owidth, height = oheight, bpp = obpp, ppdir = oppdir } + self:apply_config{ width = owidth, height = oheight, bpp = obpp, ppdir = oppdir, flipx = oflipx, flipy = oflipy } + self.extra.fb:prepare() + self.extra.fb:draw() else self.name = nname end end, apply_config = function (self, cfg) - local fb = self.extra.fb + local extra = self.extra + local fb = extra.fb local h = self:get_linked_input(1) - if cfg.width then self.extra.width = cfg.width end - if cfg.height then self.extra.height = cfg.height end - if cfg.bpp then self.extra.bpp = cfg.bpp end - if cfg.ppdir then self.extra.ppdir = cfg.ppdir end - fb.cfg = { h = h, width = self.extra.width, height = self.extra.height, bpp = self.extra.bpp } - fb:prepare() - fb:draw() - fb:action() + if cfg.width then extra.width = cfg.width end + if cfg.height then extra.height = cfg.height end + if cfg.bpp then extra.bpp = cfg.bpp end + if cfg.ppdir then extra.ppdir = cfg.ppdir end + if cfg.flipx then extra.flipx = cfg.flipx end + if cfg.flipy then extra.flipy = cfg.flipy end + if cfg.zoom then extra.zoom = cfg.zoom end + local zoom = 2 ^ extra.zoom + local posx = fb.posx + local posy = fb.posy + local dx = fb.dx + 0 + local dy = fb.dy + 0 + local fw = math.floor(extra.width * zoom) + local fh = math.floor(extra.height * zoom) + if dx >= (fb.xmax - fb.xmin) then posx = math.floor((fw - dx) / 2) end + if dy >= (fb.ymax - fb.ymin) then posy = math.floor((fh - dy) / 2) end + fb.xmax = fw + fb.ymax = fh + cfg = { + h = h, + width = extra.width, + height = extra.height, + bpp = extra.bpp, + ppdir = extra.ppdir, + flipx = extra.flipx, + flipy = extra.flipy, + zoom = zoom, + x = -posx, + y = -posy, + fw = fw, + fh = fh, + } + fb.cfg = cfg + local cvwidth, cvheight = fb.width or 0, fb.height or 0 + cvwidth, cvheight = cvwidth + 0, cvheight + 0 end, getnextbyte = function (h) @@ -133,7 +191,7 @@ dalosp.framebuffer = { local bpp = cfg.bpp local ppdir = cfg.ppdir local flipx = cfg.flipx - local flipy = cfg.flipy + local flipy = not cfg.flipy local cim = im.ImageCreate(width, height, im.RGB, im.BYTE) self.cim = cim cim:Clear() @@ -146,7 +204,7 @@ dalosp.framebuffer = { for y = 0, height - 1 do for x = 0, width - 1 do - local px, py = flipx and width - x or x, flipy and height - y or y + local px, py = flipx and width - x - 1 or x, flipy and height - y - 1 or y r[py][px], g[py][px], b[py][px] = getnextpixel(cfg) end end @@ -157,8 +215,65 @@ dalosp.framebuffer = { draw = function (self) local cvdb = self.cvdb if not cvdb then return iup.DEFAULT end - cvdb:Clear() - self.cim:cdCanvasPutImageRect(cvdb, 0, 0, 0, 0, 0, 0, 0, 0) -- use default values + cvdb:Clear() + local cim = self.cim + local cfg = self.cfg + cim:cdCanvasPutImageRect(cvdb, cfg.x, cvdb:InvertYAxis(cfg.y + cfg.fh), cfg.fw, cfg.fh, 0, 0, 0, 0) + cvdb:Flush() + end, + + resize_cb = function (self, width, height) + self.dx = width + self.dy = height + self.posx = self.posx + self.posy = self.posy + iupep.dbuffer.resize_cb(self, width, height) + self.obj:apply_config{} + self:draw() + end, + + fimg2canvas = function (self, ix, iy) + local cfg = self.cfg + local cx, cy + return ix + cfg.x, iy + cfg.y + end, + + canvas2fimg = function (self, cx, cy) + local cfg = self.cfg + return cx - cfg.x, cy - cfg.y + end, + + img2canvas = function (self, ix, iy) + local cfg = self.cfg + local cx, cy + return math.floor((ix + cfg.x) * cfg.zoom), math.floor((iy + cfg.y) * cfg.zoom) + end, + + canvas2img = function (self, cx, cy) + local cfg = self.cfg + return math.floor((cx - cfg.x) / cfg.zoom), math.floor((cy - cfg.y) / cfg.zoom) + end, + + scroll_cb = function (self, op, posx, posy) + print "Scroll called." + self:resize_cb(self.width, self.height) + end, + + wheel_cb = function (self, delta, x, y, status) + local ox, oy = self:canvas2img(x, y) + local opx, opy = self.cfg.x, self.cfg.y + self.obj:apply_config { zoom = self.obj.extra.zoom + (delta / 10) } + local nx, ny = self:img2canvas(ox, oy) + local dx, dy = ox - nx, oy - ny +-- dtable({opx = opx, opy = opy, dx = dx, dy = dy, nx = opx - dx, ny = opy - dy}, "params") +-- self.posx, self.posy = opx - dx, opy - dy + self:resize_cb(self.width, self.height) + end, + + motion_cb = function (self, x, y) + local ox, oy = self:canvas2img(x, y) + local nx, ny = self:img2canvas(ox, oy) +-- dtable({x = x, y = y, ox = ox, oy = oy, nx = nx, ny = ny}, "params") end, create = function (d, tab, settings) @@ -171,7 +286,15 @@ dalosp.framebuffer = { tab.default_name = "Framebuffer" tab.ntype = "Framebuffer" tab.get_settings = dalosp.framebuffer.get_settings - local extra = { width = settings.width or 256 , height = settings.height or 256, bpp = settings.bpp or 32, ppdir = settings.dir or 0 } + local extra = { + width = settings.width or 256, + height = settings.height or 256, + bpp = settings.bpp or 32, + ppdir = settings.dir or 0, + flipx = settings.flipx, + flipy = settings.flipy, + zoom = settings.zoom or 0, + } local obj = dalos.object(d, tab, extra) @@ -183,14 +306,81 @@ dalosp.framebuffer = { action = iupep.dbuffer.action, map_cb = iupep.dbuffer.map_cb, unmap_cb = iupep.dbuffer.unmap_cb, - resize_cb = iupep.dbuffer.resize_cb, + resize_cb = dalosp.framebuffer.resize_cb, + motion_cb = dalosp.framebuffer.motion_cb, draw = dalosp.framebuffer.draw, + scroll_cb = dalosp.framebuffer.scroll_cb, + wheel_cb = dalosp.framebuffer.wheel_cb, prepare = dalosp.framebuffer.prepare, + img2canvas = dalosp.framebuffer.img2canvas, + canvas2img = dalosp.framebuffer.canvas2img, + fimg2canvas = dalosp.framebuffer.img2canvas, + canvas2fimg = dalosp.framebuffer.canvas2img, getnextpixel = dalosp.framebuffer.getnextpixel, rastersize = extra.width .. "x" .. extra.height, + scrollbar = "Yes", + dx = 1, + dy = 1, + linex = 1, + liney = 1, + xmax = 0, + ymax = 0, + xautohide = "No", + yautohide = "No", + obj = obj, } local dlg = iup.dialog { - fb, + iup.vbox { + fb, + iup.hbox { + iup.fill{}, + iup.button { + action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = -4 } fb:resize_cb(fb.width, fb.height) end, + title = "1:16", + }, + iup.fill{}, + iup.button { + action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = -3 } fb:resize_cb(fb.width, fb.height) end, + title = "1:8", + }, + iup.fill{}, + iup.button { + action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = -2 } fb:resize_cb(fb.width, fb.height) end, + title = "1:4", + }, + iup.fill{}, + iup.button { + action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = -1 } fb:resize_cb(fb.width, fb.height) end, + title = "1:2", + }, + iup.fill{}, + iup.button { + action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 0 } fb:resize_cb(fb.width, fb.height) end, + title = "1:1", + }, + iup.fill{}, + iup.button { + action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 1 } fb:resize_cb(fb.width, fb.height) end, + title = "2:1", + }, + iup.fill{}, + iup.button { + action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 2 } fb:resize_cb(fb.width, fb.height) end, + title = "4:1", + }, + iup.fill{}, + iup.button { + action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 3 } fb:resize_cb(fb.width, fb.height) end, + title = "8:1", + }, + iup.fill{}, + iup.button { + action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 4 } fb:resize_cb(fb.width, fb.height) end, + title = "16:1", + }, + iup.fill{}, + }, + }, size = "320x200", title = obj.name, shrink = "Yes", @@ -199,6 +389,8 @@ dalosp.framebuffer = { extra.fb = fb obj:apply_config{} + fb:prepare() + fb:draw() return obj end, -- cgit v1.2.3