Speed up some screen operations

Use rectangles and texure coloring instead of redrawing the entire
texture, cuts down things by half.

Error if a component doesn't load on boot
Also fix various usage of the ffi api, so that luajit wouldn't complain.
Correct a typo on keyboard
This commit is contained in:
gamax92 2015-12-21 13:02:07 -07:00
parent d60f60087f
commit 70bf298e8b
3 changed files with 51 additions and 30 deletions

View File

@ -114,7 +114,10 @@ end
local components = settings.components
for k,v in pairs(components) do
v[2] = v[2] or k
component.connect(v)
local ok, err=component.connect(v)
if not ok then
error(err,0)
end
end
env.component = {list = component.list}

View File

@ -15,17 +15,17 @@ local function setLatest(char)
end
function elsa.textinput(event)
local textevent = ffi.cast("SDL_TextInputEvent", event)
local textevent = ffi.cast("SDL_TextInputEvent*", event)
local text = ffi.string(textevent.text)
cprint("textinput",text)
setLatest(lua_utf8.byte(text))
end
function elsa.keydown(event)
local keyevent = ffi.cast("SDL_KeyboardEvent", event)
local key = keyevent.keysym.scancode
local keyevent = ffi.cast("SDL_KeyboardEvent*", event)
local key = tonumber(keyevent.keysym.scancode)
local lwjgl = keys[key]
cprint("keydown",keyevent.keysym.scancode,lwjgl)
cprint("keydown",key,lwjgl)
-- TODO: Lovely SDL Hacks
if lwjgl ~= 1 then -- Escape
table.insert(kbdcodes,{type="key_down",addr=address,code=lwjgl or 0})
@ -41,10 +41,10 @@ function elsa.keydown(event)
end
function elsa.keyup(event)
local keyevent = ffi.cast("SDL_KeyboardEvent", event)
local key = keyevent.keysym.scancode
local keyevent = ffi.cast("SDL_KeyboardEvent*", event)
local key = tonumber(keyevent.keysym.scancode)
local lwjgl = keys[key]
cprint("keydown",keyevent.keysym.scancode,lwjgl)
cprint("keyup",key,lwjgl)
if key ~= 41 then -- Escape
table.insert(kbdcodes,{type="key_up",addr=address,code=lwjgl or 0,char=code2char[lwjgl]})
end

View File

@ -58,7 +58,7 @@ end
local buttons = {[SDL.BUTTON_LEFT] = 0, [SDL.BUTTON_RIGHT] = 1}
local moved, bttndown, lx, ly = false
function elsa.mousebuttondown(event)
local mbevent = ffi.cast("SDL_MouseButtonEvent", event)
local mbevent = ffi.cast("SDL_MouseButtonEvent*", event)
if buttons[mbevent.button] then
if not bttndown then
lx, ly = math.floor(mbevent.x/8)+1,math.floor(mbevent.y/16)+1
@ -69,7 +69,7 @@ function elsa.mousebuttondown(event)
end
function elsa.mousebuttonup(event)
local mbevent = ffi.cast("SDL_MouseButtonEvent", event)
local mbevent = ffi.cast("SDL_MouseButtonEvent*", event)
if bttndown and buttons[mbevent.button] then
if moved then
moved = false
@ -80,7 +80,7 @@ function elsa.mousebuttonup(event)
end
function elsa.mousemotion(event)
local mmevent = ffi.cast("SDL_MouseMotionEvent", event)
local mmevent = ffi.cast("SDL_MouseMotionEvent*", event)
if bttndown then
local nx, ny = math.floor(mmevent.x/8)+1,math.floor(mmevent.y/16)+1
if nx ~= lx or ny ~= ly then
@ -92,7 +92,7 @@ function elsa.mousemotion(event)
end
function elsa.mousewheel(event)
local mwevent = ffi.cast("SDL_MouseWheelEvent", event)
local mwevent = ffi.cast("SDL_MouseWheelEvent*", event)
local x,y = ffi.new("int[1]"),ffi.new("int[1]")
SDL.getMouseState(ffi.cast("int*",x), ffi.cast("int*",y))
table.insert(machine.signals,{"scroll",address,math.floor(x[0]/8)+1,math.floor(y[0]/16)+1,mwevent.y})
@ -116,6 +116,7 @@ local function createWindow()
if renderer == ffi.C.NULL then
error(ffi.string(SDL.getError()))
end
SDL.setRenderDrawBlendMode(renderer, SDL.BLENDMODE_BLEND)
texture = SDL.createTexture(renderer, SDL.PIXELFORMAT_ARGB8888, SDL.TEXTUREACCESS_TARGET, width*8, height*16);
if texture == ffi.C.NULL then
error(ffi.string(SDL.getError()))
@ -128,11 +129,10 @@ local function createWindow()
-- Initialize all the textures to black
SDL.setRenderDrawColor(renderer, 0, 0, 0, 255)
SDL.renderFillRect(renderer, ffi.C.NULL)
SDL.setRenderTarget(renderer, texture);
SDL.renderFillRect(renderer, ffi.C.NULL)
SDL.setRenderTarget(renderer, copytexture);
SDL.renderFillRect(renderer, ffi.C.NULL)
SDL.setRenderTarget(renderer, ffi.C.NULL);
SDL.setRenderTarget(renderer, texture);
SDL.renderFillRect(renderer, ffi.C.NULL)
end
local function cleanUpWindow(wind)
@ -153,17 +153,23 @@ elsa.cleanup[#elsa.cleanup+1] = function()
end
function elsa.draw()
SDL.setRenderTarget(renderer, ffi.C.NULL);
SDL.renderCopy(renderer, texture, ffi.C.NULL, ffi.C.NULL)
SDL.renderPresent(renderer)
SDL.setRenderTarget(renderer, texture);
end
local function extract(value)
return bit.rshift(bit.band(value,0xFF0000),16),
bit.rshift(bit.band(value,0xFF00),8),
bit.band(value,0xFF)
end
local charCache={}
local char8 = ffi.new("uint32_t[?]", 8*16)
local char16 = ffi.new("uint32_t[?]", 16*16)
local function renderChar(char,x,y,fg,bg)
if unifont[char] == nil then
char = 63
end
char = unifont[char]
local function _renderChar(ochar)
char = unifont[ochar]
local size,pchar = #char/16
if size == 2 then
pchar = char8
@ -176,13 +182,32 @@ local function renderChar(char,x,y,fg,bg)
local cx = 0
for j = size*4-1,0,-1 do
local bit = math.floor(line/2^j)%2
local color = bit == 0 and bg or fg
pchar[cy*size*4+cx] = color + 0xFF000000
pchar[cy*size*4+cx] = (bit == 0 and 0 or 0xFFFFFFFF)
cx = cx + 1
end
cy = cy + 1
end
SDL.updateTexture(texture, ffi.new("SDL_Rect",{x=x,y=y,w=size*4,h=16}), pchar, (size*4) * ffi.sizeof("uint32_t"))
local texture = SDL.createTexture(renderer, SDL.PIXELFORMAT_ARGB8888, SDL.TEXTUREACCESS_STATIC, size*4, 16);
SDL.setTextureBlendMode(texture, SDL.BLENDMODE_BLEND)
SDL.updateTexture(texture, ffi.C.NULL, pchar, (size*4) * ffi.sizeof("uint32_t"))
charCache[ochar] = texture
end
local function renderChar(char,x,y,fg,bg)
if unifont[char] == nil then
char = 63
end
if not charCache[char] then
_renderChar(char)
end
local br, bg, bb = extract(bg)
SDL.setRenderDrawColor(renderer, br, bg, bb, 255)
local dest = ffi.new("SDL_Rect",{x=x,y=y,w=#unifont[char]/4,h=16})
SDL.renderFillRect(renderer, dest)
if char~=32 then
SDL.setTextureColorMod(charCache[char], extract(fg))
SDL.renderCopy(renderer, charCache[char], ffi.C.NULL, dest)
end
end
local function screenSet(x,y,c)
@ -215,12 +240,6 @@ local function setPos(x,y,c,fg,bg)
end
end
local function extract(value)
return bit.rshift(bit.band(value,0xFF0000),16),
bit.rshift(bit.band(value,0xFF00),8),
bit.band(value,0xFF)
end
local function compare(value1, value2)
local r1,g1,b1 = extract(value1)
local r2,g2,b2 = extract(value2)
@ -577,7 +596,6 @@ function cec.copy(x1, y1, w, h, tx, ty) -- Copies a portion of the screen from t
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