Copy is now a lot faster

Use the magic of updateTexture that didn't exist in the old binding.
This commit is contained in:
gamax92 2015-04-25 14:17:57 -06:00
parent 3ab368da8c
commit 0004498294

View File

@ -36,74 +36,70 @@ local window = SDL.createWindow("OCEmu - screen@" .. address, SDL.WINDOWPOS_CENT
if window == ffi.C.NULL then if window == ffi.C.NULL then
error(SDL.getError()) error(SDL.getError())
end end
local renderer = SDL.createRenderer(window, -1, SDL.RENDERER_TARGETTEXTURE)
if renderer == ffi.C.NULL then
local render = SDL.createRenderer(window, -1, 0) error(SDL.getError())
if render == ffi.C.NULL then end
local texture = SDL.createTexture(renderer, SDL.PIXELFORMAT_ARGB8888, SDL.TEXTUREACCESS_TARGET, width*8, height*16);
if texture == ffi.C.NULL then
error(SDL.getError())
end
local copytexture = SDL.createTexture(renderer, SDL.PIXELFORMAT_ARGB8888, SDL.TEXTUREACCESS_TARGET, width*8, height*16);
if copytexture == ffi.C.NULL then
error(SDL.getError()) error(SDL.getError())
end end
local function breakColor(color) -- Initialize all the textures to black
return math.floor(color/65536%256), math.floor(color/256%256), math.floor(color%256) SDL.setRenderDrawColor(renderer, 0, 0, 0, 255)
end SDL.renderFillRect(renderer, ffi.C.NULL)
SDL.setRenderTarget(renderer, texture);
local lastcolor SDL.renderFillRect(renderer, ffi.C.NULL)
local function setDrawColor(color) SDL.setRenderTarget(renderer, copytexture);
if color ~= lastcolor then SDL.renderFillRect(renderer, ffi.C.NULL)
local r,g,b = breakColor(color) SDL.setRenderTarget(renderer, ffi.C.NULL);
SDL.setRenderDrawColor(render, r, g, b, 255)
lastcolor = color
end
end
setDrawColor(0)
SDL.renderClear(render)
function elsa.draw() function elsa.draw()
SDL.showWindow(window) SDL.showWindow(window)
SDL.renderPresent(render) SDL.renderCopy(renderer, texture, ffi.C.NULL, ffi.C.NULL)
SDL.renderPresent(renderer)
end end
local points = {} local char8 = ffi.new("uint32_t[?]", 8*16);
local char16 = ffi.new("uint32_t[?]", 16*16);
local function renderChar(char,x,y,fg,bg) local function renderChar(char,x,y,fg,bg)
if unifont[char] ~= nil then if unifont[char] == nil then
char = 63
end
char = unifont[char] char = unifont[char]
local size = #char/16 local size,pchar = #char/16
if size == 2 then
pchar = char8
else
pchar = char16
end
local cy = 0
for i = 1,#char,size do for i = 1,#char,size do
local line = tonumber(char:sub(i,i+size-1),16) local line = tonumber(char:sub(i,i+size-1),16)
local cx = x local cx = 0
for j = size*4-1,0,-1 do for j = size*4-1,0,-1 do
local bit = math.floor(line/2^j)%2 local bit = math.floor(line/2^j)%2
local color = bit == 0 and bg or fg local color = bit == 0 and bg or fg
if x >= 0 and y >= 0 and x < width * 8 and y < height * 16 then pchar[cy*size*4+cx] = color + 0xFF000000
if points[color] == nil then
points[color] = {}
end
points[color][#points[color]+1] = ffi.new("SDL_Point", {x=cx, y=y})
end
cx = cx + 1 cx = cx + 1
end end
y = y + 1 cy = cy + 1
end end
end SDL.updateTexture(texture, ffi.new("SDL_Rect",{x=x,y=y,w=size*4,h=16}), pchar, (size*4) * ffi.sizeof("uint32_t"))
end
local function drawPoints()
for color,list in pairs(points) do
setDrawColor(color)
SDL.renderDrawPoints(render, ffi.new("SDL_Point[?]",#list,list), #list)
end
points = {}
end end
local function setPos(x,y,c,fg,bg) local function setPos(x,y,c,fg,bg)
local change = screen.txt[y][x] ~= utf8.char(c) or screen.fg[y][x] ~= scrfgc or screen.bg[y][x] ~= scrbgc or screen.fgp[y][x] ~= scrfgp or screen.bgp[y][x] ~= scrbgp local renderchange = screen.txt[y][x] ~= utf8.char(c) or screen.bg[y][x] ~= scrbgc or (screen.txt[y][x] ~= " " and screen.fg[y][x] ~= scrfgc)
if change then
screen.txt[y][x] = utf8.char(c) screen.txt[y][x] = utf8.char(c)
screen.fg[y][x] = scrfgc screen.fg[y][x] = scrfgc
screen.bg[y][x] = scrbgc screen.bg[y][x] = scrbgc
screen.fgp[y][x] = scrfgp screen.fgp[y][x] = scrfgp
screen.bgp[y][x] = scrbgp screen.bgp[y][x] = scrbgp
if renderchange then
renderChar(c,(x-1)*8,(y-1)*16,fg,bg) renderChar(c,(x-1)*8,(y-1)*16,fg,bg)
end end
end end
@ -199,7 +195,7 @@ function cec.maxDepth() -- Get the maximum supported color depth.
return maxtier return maxtier
end end
function cec.fill(x1, y1, w, h, char) -- Fills a portion of the screen at the specified position with the specified size with the specified character. function cec.fill(x1, y1, w, h, char) -- Fills a portion of the screen at the specified position with the specified size with the specified character.
--STUB --TODO
cprint("(cec) screen.fill", x1, y1, w, h, char) cprint("(cec) screen.fill", x1, y1, w, h, char)
if w <= 0 or h <= 0 then if w <= 0 or h <= 0 then
return true return true
@ -215,7 +211,6 @@ function cec.fill(x1, y1, w, h, char) -- Fills a portion of the screen at the sp
setPos(x,y,code,scrfgc,scrbgc) setPos(x,y,code,scrfgc,scrbgc)
end end
end end
drawPoints()
end end
function cec.getResolution() -- Get the current screen resolution. function cec.getResolution() -- Get the current screen resolution.
cprint("(cec) screen.getResolution") cprint("(cec) screen.getResolution")
@ -261,7 +256,6 @@ function cec.set(x, y, value, vertical) -- Plots a string value to the screen at
if x > width then break end if x > width then break end
end end
end end
drawPoints()
return true return true
end end
function cec.copy(x1, y1, w, h, tx, ty) -- Copies a portion of the screen from the specified location with the specified size by the specified translation. function cec.copy(x1, y1, w, h, tx, ty) -- Copies a portion of the screen from the specified location with the specified size by the specified translation.
@ -293,19 +287,20 @@ function cec.copy(x1, y1, w, h, tx, ty) -- Copies a portion of the screen from t
end end
for y = math.max(math.min(y1+ty, height), 1), math.max(math.min(y2+ty, height), 1) do for y = math.max(math.min(y1+ty, height), 1), math.max(math.min(y2+ty, height), 1) do
for x = math.max(math.min(x1+tx, width), 1), math.max(math.min(x2+tx, width), 1) do for x = math.max(math.min(x1+tx, width), 1), math.max(math.min(x2+tx, width), 1) do
local change = screen.txt[y][x] ~= copy.txt[y-y1-ty][x-x1-tx] or screen.fg[y][x] ~= copy.fg[y-y1-ty][x-x1-tx] or screen.bg[y][x] ~= copy.bg[y-y1-ty][x-x1-tx] or screen.fgp[y][x] ~= copy.fgp[y-y1-ty][x-x1-tx] or screen.bgp[y][x] ~= copy.bgp[y-y1-ty][x-x1-tx] local renderchange = screen.txt[y][x] ~= copy.txt[y-y1-ty][x-x1-tx] or screen.bg[y][x] ~= copy.bg[y-y1-ty][x-x1-tx] or (screen.txt[y][x] ~= " " and screen.fg[y][x] ~= copy.fg[y-y1-ty][x-x1-tx])
if change then
screen.txt[y][x] = copy.txt[y-y1-ty][x-x1-tx] screen.txt[y][x] = copy.txt[y-y1-ty][x-x1-tx]
screen.fg[y][x] = copy.fg[y-y1-ty][x-x1-tx] screen.fg[y][x] = copy.fg[y-y1-ty][x-x1-tx]
screen.bg[y][x] = copy.bg[y-y1-ty][x-x1-tx] screen.bg[y][x] = copy.bg[y-y1-ty][x-x1-tx]
screen.fgp[y][x] = copy.fgp[y-y1-ty][x-x1-tx] screen.fgp[y][x] = copy.fgp[y-y1-ty][x-x1-tx]
screen.bgp[y][x] = copy.bgp[y-y1-ty][x-x1-tx] screen.bgp[y][x] = copy.bgp[y-y1-ty][x-x1-tx]
-- Speedup somehow D:
renderChar(utf8.byte(copy.txt[y-y1-ty][x-x1-tx]),(x-1)*8,(y-1)*16,copy.fg[y-y1-ty][x-x1-tx],copy.bg[y-y1-ty][x-x1-tx])
end end
end end
end SDL.updateTexture(texture, ffi.C.NULL, pixels, (width*8) * ffi.sizeof("uint32_t"))
drawPoints() SDL.setRenderTarget(renderer, copytexture);
SDL.renderCopy(renderer, texture, ffi.C.NULL, ffi.C.NULL)
SDL.renderCopy(renderer, texture, ffi.new("SDL_Rect",{x=(x1-1)*8,y=(y1-1)*16,w=w*8,h=h*16}), ffi.new("SDL_Rect",{x=(x1+tx-1)*8,y=(y1+ty-1)*16,w=w*8,h=h*16}))
SDL.setRenderTarget(renderer, ffi.C.NULL);
texture,copytexture=copytexture,texture
end end
return obj,cec return obj,cec