add dedicated backend (WIP)

This commit is contained in:
airstruck
2015-11-22 12:36:44 -05:00
parent 97b2332d47
commit bbba7e1b3d
23 changed files with 6073 additions and 235 deletions

288
luigi/backend/ffisdl.lua Normal file
View File

@@ -0,0 +1,288 @@
local ROOT = (...):gsub('[^.]*.[^.]*$', '')
local Hooker = require(ROOT .. 'hooker')
local ffi = require 'ffi'
local sdl = require((...) .. '.sdl')
local Image = require((...) .. '.image')
local Font = require((...) .. '.font')
local Keyboard = require((...) .. '.keyboard')
local IntOut = ffi.typeof 'int[1]'
-- create window and renderer
local window = sdl.createWindow('', 0, 0, 800, 600,
sdl.WINDOW_SHOWN)
if window == nil then
io.stderr:write(ffi.string(sdl.getError()))
sdl.quit()
os.exit(1)
end
ffi.gc(window, sdl.destroyWindow)
local renderer = sdl.createRenderer(window, -1,
sdl.RENDERER_ACCELERATED + sdl.RENDERER_PRESENTVSYNC)
if renderer == nil then
io.stderr:write(ffi.string(sdl.getError()))
sdl.quit()
os.exit(1)
end
ffi.gc(renderer, sdl.destroyRenderer)
local Backend = {}
local callback = {
draw = function () end,
resize = function () end,
mousepressed = function () end,
mousereleased = function () end,
mousemoved = function () end,
keypressed = function () end,
keyreleased = function () end,
textinput = function () end,
}
Backend.run = function ()
local event = sdl.Event()
while true do
sdl.pumpEvents()
while sdl.pollEvent(event) ~= 0 do
if event.type == sdl.QUIT then
return
elseif event.type == sdl.WINDOWEVENT
and event.window.event == sdl.WINDOWEVENT_RESIZED then
callback.resize(event.window.data1, event.window.data2)
elseif event.type == sdl.MOUSEBUTTONDOWN then
callback.mousepressed(event.button.x, event.button.y, event.button.button)
elseif event.type == sdl.MOUSEBUTTONUP then
callback.mousereleased(event.button.x, event.button.y, event.button.button)
elseif event.type == sdl.MOUSEMOTION then
callback.mousemoved(event.motion.x, event.motion.y)
elseif event.type == sdl.KEYDOWN then
local key = Keyboard.stringByKeycode[event.key.keysym.sym]
callback.keypressed(key, event.key['repeat'])
elseif event.type == sdl.KEYUP then
local key = Keyboard.stringByKeycode[event.key.keysym.sym]
callback.keyreleased(key, event.key['repeat'])
elseif event.type == sdl.TEXTINPUT then
callback.textinput(ffi.string(event.text.text))
end
end
sdl.setRenderDrawColor(renderer, 0, 0, 0, 255)
sdl.renderClear(renderer)
callback.draw()
sdl.renderPresent(renderer)
sdl.delay(1)
end
end
Backend.Cursor = function (image, x, y)
return sdl.createColorCursor(image.sdlSurface, x, y)
end
Backend.Font = Font
Backend.Image = function (path)
return Image(renderer, path)
end
Backend.Quad = function (x, y, w, h)
return { x, y, w, h }
end
Backend.SpriteBatch = require((...) .. '.spritebatch')
Backend.draw = function (drawable, x, y, sx, sy)
return drawable:draw(x, y, sx, sy)
end
Backend.drawRectangle = function (mode, x, y, w, h)
if mode == 'fill' then
sdl.renderFillRect(renderer, sdl.Rect(x, y, w, h))
else
sdl.renderDrawRect(renderer, sdl.Rect(x, y, w, h))
end
end
local currentFont = Font()
-- print( text, x, y, r, sx, sy, ox, oy, kx, ky )
Backend.print = function (text, x, y)
if not text or text == '' then return end
local font = currentFont.sdlFont
local color = sdl.Color(currentFont.color)
local write = Font.SDL2_ttf.TTF_RenderUTF8_Blended
local surface = write(font, text, color)
ffi.gc(surface, sdl.freeSurface)
local texture = sdl.createTextureFromSurface(renderer, surface)
ffi.gc(texture, sdl.destroyTexture)
sdl.renderCopy(renderer, texture, nil, sdl.Rect(x, y, surface.w, surface.h))
end
Backend.printf = Backend.print
Backend.getClipboardText = sdl.getClipboardText
Backend.setClipboardText = sdl.setClipboardText
Backend.getMousePosition = function ()
local x, y = IntOut(), IntOut()
sdl.getMouseState(x, y)
return x[0], y[0]
end
local function SystemCursor (id)
local cursor = sdl.createSystemCursor(id)
ffi.gc(cursor, sdl.freeCursor)
return cursor
end
local systemCursors = {
arrow = SystemCursor(sdl.SYSTEM_CURSOR_ARROW),
ibeam = SystemCursor(sdl.SYSTEM_CURSOR_IBEAM),
wait = SystemCursor(sdl.SYSTEM_CURSOR_WAIT),
crosshair = SystemCursor(sdl.SYSTEM_CURSOR_CROSSHAIR),
waitarrow = SystemCursor(sdl.SYSTEM_CURSOR_WAITARROW),
sizenwse = SystemCursor(sdl.SYSTEM_CURSOR_SIZENWSE),
sizenesw = SystemCursor(sdl.SYSTEM_CURSOR_SIZENESW),
sizewe = SystemCursor(sdl.SYSTEM_CURSOR_SIZEWE),
sizens = SystemCursor(sdl.SYSTEM_CURSOR_SIZENS),
sizeall = SystemCursor(sdl.SYSTEM_CURSOR_SIZEALL),
no = SystemCursor(sdl.SYSTEM_CURSOR_NO),
hand = SystemCursor(sdl.SYSTEM_CURSOR_HAND),
}
Backend.getSystemCursor = function (name)
return systemCursors[name] or systemCursors.arrow
end
Backend.getWindowSize = function ()
local x, y = IntOut(), IntOut()
sdl.getWindowSize(window, x, y)
return x[0], y[0]
end
Backend.getTime = function ()
return sdl.getTicks() * 0.001
end
Backend.isKeyDown = function (...)
local state = sdl.getKeyboardState(nil)
for i = 1, select('#', ...) do
local name = select(i, ...)
local scan = Keyboard.scancodeByString[name]
if scan and state[scan] ~= 0 then
return true
end
end
return false
end
Backend.isMouseDown = function ()
end
Backend.quit = function ()
sdl.quit()
os.exit()
end
local lastColor
Backend.setColor = function (color)
lastColor = color
sdl.setRenderDrawColor(renderer,
color[1], color[2], color[3], color[4] or 255)
end
Backend.setCursor = function (cursor)
sdl.setCursor(cursor or Backend.getSystemCursor('arrow'))
end
Backend.setFont = function (font)
currentFont = font
end
local lastScissor
Backend.setScissor = function (x, y, w, h)
lastScissor = x and sdl.Rect(x, y, w, h)
sdl.renderSetClipRect(renderer, lastScissor)
end
function Backend.hide (layout)
for _, item in ipairs(layout.hooks) do
Hooker.unhook(item)
end
layout.hooks = {}
end
local function hook (layout, key, method, hookLast)
layout.hooks[#layout.hooks + 1] = Hooker.hook(
callback, key, method, hookLast)
end
local stack = {}
Backend.pop = function ()
local history = stack[#stack]
Backend.setColor(history.color or { 0, 0, 0, 255 })
Backend.setScissor(history.scissor)
stack[#stack] = nil
end
Backend.push = function ()
stack[#stack + 1] = {
color = lastColor,
scissor = lastScissor,
}
end
local isMouseDown = function ()
return sdl.getMouseState(nil, nil) > 0
end
function Backend.show (layout)
local input = layout.input
hook(layout, 'draw', function ()
input:handleDisplay(layout)
end, true)
hook(layout, 'resize', function (width, height)
return input:handleReshape(layout, width, height)
end)
hook(layout, 'mousepressed', function (x, y, button)
return input:handlePressStart(layout, button, x, y)
end)
hook(layout, 'mousereleased', function (x, y, button)
return input:handlePressEnd(layout, button, x, y)
end)
hook(layout, 'mousemoved', function (x, y, dx, dy)
if isMouseDown() then
return input:handlePressedMove(layout, x, y)
else
return input:handleMove(layout, x, y)
end
end)
hook(layout, 'keypressed', function (key, isRepeat)
return input:handleKeyPress(layout, key, Backend.getMousePosition())
end)
hook(layout, 'keyreleased', function (key)
return input:handleKeyRelease(layout, key, Backend.getMousePosition())
end)
hook(layout, 'textinput', function (text)
return input:handleTextInput(layout, text, Backend.getMousePosition())
end)
end
return Backend

View File

@@ -0,0 +1,270 @@
local REL = (...):gsub('[^.]*$', '')
local ffi = require 'ffi'
local sdl = require(REL .. 'sdl')
local SDL2_ttf = ffi.load 'SDL2_ttf'
local IntOut = ffi.typeof 'int[1]'
ffi.cdef [[
/* The internal structure containing font information */
typedef struct _TTF_Font TTF_Font;
/* Initialize the TTF engine - returns 0 if successful, -1 on error */
int TTF_Init(void);
/* Open a font file and create a font of the specified point size.
* Some .fon fonts will have several sizes embedded in the file, so the
* point size becomes the index of choosing which size. If the value
* is too high, the last indexed size will be the default. */
TTF_Font *TTF_OpenFont(const char *file, int ptsize);
TTF_Font *TTF_OpenFontIndex(const char *file, int ptsize, long index);
TTF_Font *TTF_OpenFontRW(SDL_RWops *src, int freesrc, int ptsize);
TTF_Font *TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index);
/* Set and retrieve the font style
#define TTF_STYLE_NORMAL 0x00
#define TTF_STYLE_BOLD 0x01
#define TTF_STYLE_ITALIC 0x02
#define TTF_STYLE_UNDERLINE 0x04
#define TTF_STYLE_STRIKETHROUGH 0x08
*/
int TTF_GetFontStyle(const TTF_Font *font);
void TTF_SetFontStyle(TTF_Font *font, int style);
int TTF_GetFontOutline(const TTF_Font *font);
void TTF_SetFontOutline(TTF_Font *font, int outline);
/* Set and retrieve FreeType hinter settings
#define TTF_HINTING_NORMAL 0
#define TTF_HINTING_LIGHT 1
#define TTF_HINTING_MONO 2
#define TTF_HINTING_NONE 3
*/
int TTF_GetFontHinting(const TTF_Font *font);
void TTF_SetFontHinting(TTF_Font *font, int hinting);
/* Get the total height of the font - usually equal to point size */
int TTF_FontHeight(const TTF_Font *font);
/* Get the offset from the baseline to the top of the font
This is a positive value, relative to the baseline.
*/
int TTF_FontAscent(const TTF_Font *font);
/* Get the offset from the baseline to the bottom of the font
This is a negative value, relative to the baseline.
*/
int TTF_FontDescent(const TTF_Font *font);
/* Get the recommended spacing between lines of text for this font */
int TTF_FontLineSkip(const TTF_Font *font);
/* Get/Set whether or not kerning is allowed for this font */
int TTF_GetFontKerning(const TTF_Font *font);
void TTF_SetFontKerning(TTF_Font *font, int allowed);
/* Get the number of faces of the font */
long TTF_FontFaces(const TTF_Font *font);
/* Get the font face attributes, if any */
int TTF_FontFaceIsFixedWidth(const TTF_Font *font);
char *TTF_FontFaceFamilyName(const TTF_Font *font);
char *TTF_FontFaceStyleName(const TTF_Font *font);
/* Check wether a glyph is provided by the font or not */
int TTF_GlyphIsProvided(const TTF_Font *font, Uint16 ch);
/* Get the metrics (dimensions) of a glyph
To understand what these metrics mean, here is a useful link:
http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
*/
int TTF_GlyphMetrics(TTF_Font *font, Uint16 ch,
int *minx, int *maxx,
int *miny, int *maxy, int *advance);
/* Get the dimensions of a rendered string of text */
int TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h);
int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h);
int TTF_SizeUTF8_Wrapped(TTF_Font *font, const char *text, int wrapLength, int *w, int *h, int *lineCount);
int TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h);
/* Create an 8-bit palettized surface and render the given text at
fast quality with the given font and color. The 0 pixel is the
colorkey, giving a transparent background, and the 1 pixel is set
to the text color.
This function returns the new surface, or NULL if there was an error.
*/
SDL_Surface *TTF_RenderText_Solid(TTF_Font *font,
const char *text, SDL_Color fg);
SDL_Surface *TTF_RenderUTF8_Solid(TTF_Font *font,
const char *text, SDL_Color fg);
SDL_Surface *TTF_RenderUNICODE_Solid(TTF_Font *font,
const Uint16 *text, SDL_Color fg);
/* Create an 8-bit palettized surface and render the given glyph at
fast quality with the given font and color. The 0 pixel is the
colorkey, giving a transparent background, and the 1 pixel is set
to the text color. The glyph is rendered without any padding or
centering in the X direction, and aligned normally in the Y direction.
This function returns the new surface, or NULL if there was an error.
*/
SDL_Surface *TTF_RenderGlyph_Solid(TTF_Font *font,
Uint16 ch, SDL_Color fg);
/* Create an 8-bit palettized surface and render the given text at
high quality with the given font and colors. The 0 pixel is background,
while other pixels have varying degrees of the foreground color.
This function returns the new surface, or NULL if there was an error.
*/
SDL_Surface *TTF_RenderText_Shaded(TTF_Font *font,
const char *text, SDL_Color fg, SDL_Color bg);
SDL_Surface *TTF_RenderUTF8_Shaded(TTF_Font *font,
const char *text, SDL_Color fg, SDL_Color bg);
SDL_Surface *TTF_RenderUNICODE_Shaded(TTF_Font *font,
const Uint16 *text, SDL_Color fg, SDL_Color bg);
/* Create an 8-bit palettized surface and render the given glyph at
high quality with the given font and colors. The 0 pixel is background,
while other pixels have varying degrees of the foreground color.
The glyph is rendered without any padding or centering in the X
direction, and aligned normally in the Y direction.
This function returns the new surface, or NULL if there was an error.
*/
SDL_Surface *TTF_RenderGlyph_Shaded(TTF_Font *font,
Uint16 ch, SDL_Color fg, SDL_Color bg);
/* Create a 32-bit ARGB surface and render the given text at high quality,
using alpha blending to dither the font with the given color.
This function returns the new surface, or NULL if there was an error.
*/
SDL_Surface *TTF_RenderText_Blended(TTF_Font *font,
const char *text, SDL_Color fg);
SDL_Surface *TTF_RenderUTF8_Blended(TTF_Font *font,
const char *text, SDL_Color fg);
SDL_Surface *TTF_RenderUNICODE_Blended(TTF_Font *font,
const Uint16 *text, SDL_Color fg);
/* Create a 32-bit ARGB surface and render the given text at high quality,
using alpha blending to dither the font with the given color.
Text is wrapped to multiple lines on line endings and on word boundaries
if it extends beyond wrapLength in pixels.
This function returns the new surface, or NULL if there was an error.
*/
SDL_Surface *TTF_RenderText_Blended_Wrapped(TTF_Font *font,
const char *text, SDL_Color fg, Uint32 wrapLength);
SDL_Surface *TTF_RenderUTF8_Blended_Wrapped(TTF_Font *font,
const char *text, SDL_Color fg, Uint32 wrapLength);
SDL_Surface *TTF_RenderUNICODE_Blended_Wrapped(TTF_Font *font,
const Uint16 *text, SDL_Color fg, Uint32 wrapLength);
/* Create a 32-bit ARGB surface and render the given glyph at high quality,
using alpha blending to dither the font with the given color.
The glyph is rendered without any padding or centering in the X
direction, and aligned normally in the Y direction.
This function returns the new surface, or NULL if there was an error.
*/
SDL_Surface *TTF_RenderGlyph_Blended(TTF_Font *font,
Uint16 ch, SDL_Color fg);
/* Close an opened font file */
void TTF_CloseFont(TTF_Font *font);
/* De-initialize the TTF engine */
void TTF_Quit(void);
/* Check if the TTF engine is initialized */
int TTF_WasInit(void);
/* Get the kerning size of two glyphs */
int TTF_GetFontKerningSize(TTF_Font *font, int prev_index, int index);
]]
if SDL2_ttf.TTF_Init() ~= 0 then
error(ffi.string(sdl.getError()))
end
local Font = setmetatable({}, { __call = function (self, ...)
local object = setmetatable({}, { __index = self })
return object, self.constructor(object, ...)
end })
Font.SDL2_ttf = SDL2_ttf
local fontCache = {}
function Font:constructor (path, size, color)
if not size then
size = 12
end
if not color then
color = { 0, 0, 0, 255 }
end
if not path then
path = REL:gsub('%.', '/') .. 'resource/DejaVuSans.ttf'
end
local key = path .. '_' .. size
if not fontCache[key] then
local font = SDL2_ttf.TTF_OpenFont(path, size)
if font == nil then
io.stderr:write(ffi.string(sdl.getError()))
sdl.quit()
os.exit(1)
end
fontCache[key] = font
end
self.sdlFont = fontCache[key]
self.color = color
end
function Font:setAlignment (align)
self.align = align
end
function Font:setWidth (width)
self.width = width
end
function Font:getLineHeight ()
return SDL2_ttf.TTF_FontHeight(self.sdlFont)
end
function Font:getAscender ()
return SDL2_ttf.TTF_FontAscent(self.sdlFont)
end
function Font:getDescender ()
return SDL2_ttf.TTF_FontDescent(self.sdlFont)
end
function Font:getAdvance (text)
local w, h = IntOut(), IntOut()
SDL2_ttf.TTF_SizeUTF8(self.sdlFont, text, w, h)
return w[0]
end
function Font:getWrappedHeight (text)
--[[
-- TTF_Font *font, const char *text, int wrapLength, int *w, int *h, int *lineCount
local w, h, lineCount = IntOut(), IntOut(), IntOut()
SDL2_ttf.TTF_SizeUTF8_Wrapped(self.sdlFont, text, self.width,
w, h, lineCount)
return self:getLineHeight() * lineCount
--]]
local w, h = IntOut(), IntOut()
SDL2_ttf.TTF_SizeUTF8(self.sdlFont, text, w, h)
return h[0]
end
return Font

View File

@@ -0,0 +1,46 @@
local REL = (...):gsub('[^.]*$', '')
local ffi = require 'ffi'
local sdl = require(REL .. 'sdl')
local SDL2_image = ffi.load 'SDL2_image'
ffi.cdef [[ SDL_Surface *IMG_Load(const char *file); ]]
local Image = setmetatable({}, { __call = function (self, ...)
local object = setmetatable({}, { __index = self })
return object, self.constructor(object, ...)
end })
function Image:constructor (renderer, path)
self.sdlRenderer = renderer
self.sdlSurface = SDL2_image.IMG_Load(path)
ffi.gc(self.sdlSurface, sdl.freeSurface)
self.sdlTexture = sdl.createTextureFromSurface(renderer, self.sdlSurface)
ffi.gc(self.sdlTexture, sdl.destroyTexture)
self.width = self.sdlSurface.w
self.height = self.sdlSurface.h
end
function Image:getWidth ()
return self.width
end
function Image:getHeight ()
return self.height
end
function Image:draw (x, y, sx, sy)
local w = self.width * (sx or 1)
local h = self.height * (sy or 1)
-- HACK. Somehow drawing something first prevents renderCopy from
-- incorrectly scaling up in some cases (after rendering slices).
-- For example http://stackoverflow.com/questions/28218906
sdl.renderDrawPoint(self.sdlRenderer, -1, -1)
-- Draw the image.
sdl.renderCopy(self.sdlRenderer, self.sdlTexture, nil, sdl.Rect(x, y, w, h))
end
return Image

View File

@@ -0,0 +1,494 @@
local REL = (...):gsub('[^.]*$', '')
local sdl = require(REL .. 'sdl')
local Keyboard = {
scancodeByString = {},
stringByScancode = {},
keycodeByString = {},
stringByKeycode = {},
}
local function registerScancodes (registry)
for _, entry in ipairs(registry) do
Keyboard.scancodeByString[entry[1]] = entry[2]
Keyboard.stringByScancode[entry[2]] = entry[1]
end
end
local function registerKeycodes (registry)
for _, entry in ipairs(registry) do
Keyboard.keycodeByString[entry[1]] = entry[2]
Keyboard.stringByKeycode[entry[2]] = entry[1]
end
end
registerScancodes {
{ "unknown", sdl.SCANCODE_UNKNOWN },
{ "a", sdl.SCANCODE_A },
{ "b", sdl.SCANCODE_B },
{ "c", sdl.SCANCODE_C },
{ "d", sdl.SCANCODE_D },
{ "e", sdl.SCANCODE_E },
{ "f", sdl.SCANCODE_F },
{ "g", sdl.SCANCODE_G },
{ "h", sdl.SCANCODE_H },
{ "i", sdl.SCANCODE_I },
{ "j", sdl.SCANCODE_J },
{ "k", sdl.SCANCODE_K },
{ "l", sdl.SCANCODE_L },
{ "m", sdl.SCANCODE_M },
{ "n", sdl.SCANCODE_N },
{ "o", sdl.SCANCODE_O },
{ "p", sdl.SCANCODE_P },
{ "q", sdl.SCANCODE_Q },
{ "r", sdl.SCANCODE_R },
{ "s", sdl.SCANCODE_S },
{ "t", sdl.SCANCODE_T },
{ "u", sdl.SCANCODE_U },
{ "v", sdl.SCANCODE_V },
{ "w", sdl.SCANCODE_W },
{ "x", sdl.SCANCODE_X },
{ "y", sdl.SCANCODE_Y },
{ "z", sdl.SCANCODE_Z },
{ "1", sdl.SCANCODE_1 },
{ "2", sdl.SCANCODE_2 },
{ "3", sdl.SCANCODE_3 },
{ "4", sdl.SCANCODE_4 },
{ "5", sdl.SCANCODE_5 },
{ "6", sdl.SCANCODE_6 },
{ "7", sdl.SCANCODE_7 },
{ "8", sdl.SCANCODE_8 },
{ "9", sdl.SCANCODE_9 },
{ "0", sdl.SCANCODE_0 },
{ "return", sdl.SCANCODE_RETURN },
{ "escape", sdl.SCANCODE_ESCAPE },
{ "backspace", sdl.SCANCODE_BACKSPACE },
{ "tab", sdl.SCANCODE_TAB },
{ "space", sdl.SCANCODE_SPACE },
{ "-", sdl.SCANCODE_MINUS },
{ "=", sdl.SCANCODE_EQUALS },
{ "[", sdl.SCANCODE_LEFTBRACKET },
{ "]", sdl.SCANCODE_RIGHTBRACKET },
{ "\\", sdl.SCANCODE_BACKSLASH },
{ "nonus#", sdl.SCANCODE_NONUSHASH },
{ ";", sdl.SCANCODE_SEMICOLON },
{ "'", sdl.SCANCODE_APOSTROPHE },
{ "`", sdl.SCANCODE_GRAVE },
{ ",", sdl.SCANCODE_COMMA },
{ ".", sdl.SCANCODE_PERIOD },
{ "/", sdl.SCANCODE_SLASH },
{ "capslock", sdl.SCANCODE_CAPSLOCK },
{ "f1", sdl.SCANCODE_F1 },
{ "f2", sdl.SCANCODE_F2 },
{ "f3", sdl.SCANCODE_F3 },
{ "f4", sdl.SCANCODE_F4 },
{ "f5", sdl.SCANCODE_F5 },
{ "f6", sdl.SCANCODE_F6 },
{ "f7", sdl.SCANCODE_F7 },
{ "f8", sdl.SCANCODE_F8 },
{ "f9", sdl.SCANCODE_F9 },
{ "f10", sdl.SCANCODE_F10 },
{ "f11", sdl.SCANCODE_F11 },
{ "f12", sdl.SCANCODE_F12 },
{ "printscreen", sdl.SCANCODE_PRINTSCREEN },
{ "scrolllock", sdl.SCANCODE_SCROLLLOCK },
{ "pause", sdl.SCANCODE_PAUSE },
{ "insert", sdl.SCANCODE_INSERT },
{ "home", sdl.SCANCODE_HOME },
{ "pageup", sdl.SCANCODE_PAGEUP },
{ "delete", sdl.SCANCODE_DELETE },
{ "end", sdl.SCANCODE_END },
{ "pagedown", sdl.SCANCODE_PAGEDOWN },
{ "right", sdl.SCANCODE_RIGHT },
{ "left", sdl.SCANCODE_LEFT },
{ "down", sdl.SCANCODE_DOWN },
{ "up", sdl.SCANCODE_UP },
{ "numlock", sdl.SCANCODE_NUMLOCKCLEAR },
{ "kp/", sdl.SCANCODE_KP_DIVIDE },
{ "kp*", sdl.SCANCODE_KP_MULTIPLY },
{ "kp-", sdl.SCANCODE_KP_MINUS },
{ "kp+", sdl.SCANCODE_KP_PLUS },
{ "kpenter", sdl.SCANCODE_KP_ENTER },
{ "kp1", sdl.SCANCODE_KP_1 },
{ "kp2", sdl.SCANCODE_KP_2 },
{ "kp3", sdl.SCANCODE_KP_3 },
{ "kp4", sdl.SCANCODE_KP_4 },
{ "kp5", sdl.SCANCODE_KP_5 },
{ "kp6", sdl.SCANCODE_KP_6 },
{ "kp7", sdl.SCANCODE_KP_7 },
{ "kp8", sdl.SCANCODE_KP_8 },
{ "kp9", sdl.SCANCODE_KP_9 },
{ "kp0", sdl.SCANCODE_KP_0 },
{ "kp.", sdl.SCANCODE_KP_PERIOD },
{ "nonusbackslash", sdl.SCANCODE_NONUSBACKSLASH },
{ "application", sdl.SCANCODE_APPLICATION },
{ "power", sdl.SCANCODE_POWER },
{ "=", sdl.SCANCODE_KP_EQUALS },
{ "f13", sdl.SCANCODE_F13 },
{ "f14", sdl.SCANCODE_F14 },
{ "f15", sdl.SCANCODE_F15 },
{ "f16", sdl.SCANCODE_F16 },
{ "f17", sdl.SCANCODE_F17 },
{ "f18", sdl.SCANCODE_F18 },
{ "f19", sdl.SCANCODE_F19 },
{ "f20", sdl.SCANCODE_F20 },
{ "f21", sdl.SCANCODE_F21 },
{ "f22", sdl.SCANCODE_F22 },
{ "f23", sdl.SCANCODE_F23 },
{ "f24", sdl.SCANCODE_F24 },
{ "execute", sdl.SCANCODE_EXECUTE },
{ "help", sdl.SCANCODE_HELP },
{ "menu", sdl.SCANCODE_MENU },
{ "select", sdl.SCANCODE_SELECT },
{ "stop", sdl.SCANCODE_STOP },
{ "again", sdl.SCANCODE_AGAIN },
{ "undo", sdl.SCANCODE_UNDO },
{ "cut", sdl.SCANCODE_CUT },
{ "copy", sdl.SCANCODE_COPY },
{ "paste", sdl.SCANCODE_PASTE },
{ "find", sdl.SCANCODE_FIND },
{ "mute", sdl.SCANCODE_MUTE },
{ "volumeup", sdl.SCANCODE_VOLUMEUP },
{ "volumedown", sdl.SCANCODE_VOLUMEDOWN },
{ "kp,", sdl.SCANCODE_KP_COMMA },
{ "kp=400", sdl.SCANCODE_KP_EQUALSAS400 },
{ "international1", sdl.SCANCODE_INTERNATIONAL1 },
{ "international2", sdl.SCANCODE_INTERNATIONAL2 },
{ "international3", sdl.SCANCODE_INTERNATIONAL3 },
{ "international4", sdl.SCANCODE_INTERNATIONAL4 },
{ "international5", sdl.SCANCODE_INTERNATIONAL5 },
{ "international6", sdl.SCANCODE_INTERNATIONAL6 },
{ "international7", sdl.SCANCODE_INTERNATIONAL7 },
{ "international8", sdl.SCANCODE_INTERNATIONAL8 },
{ "international9", sdl.SCANCODE_INTERNATIONAL9 },
{ "lang1", sdl.SCANCODE_LANG1 },
{ "lang2", sdl.SCANCODE_LANG2 },
{ "lang3", sdl.SCANCODE_LANG3 },
{ "lang4", sdl.SCANCODE_LANG4 },
{ "lang5", sdl.SCANCODE_LANG5 },
{ "lang6", sdl.SCANCODE_LANG6 },
{ "lang7", sdl.SCANCODE_LANG7 },
{ "lang8", sdl.SCANCODE_LANG8 },
{ "lang9", sdl.SCANCODE_LANG9 },
{ "alterase", sdl.SCANCODE_ALTERASE },
{ "sysreq", sdl.SCANCODE_SYSREQ },
{ "cancel", sdl.SCANCODE_CANCEL },
{ "clear", sdl.SCANCODE_CLEAR },
{ "prior", sdl.SCANCODE_PRIOR },
{ "return2", sdl.SCANCODE_RETURN2 },
{ "separator", sdl.SCANCODE_SEPARATOR },
{ "out", sdl.SCANCODE_OUT },
{ "oper", sdl.SCANCODE_OPER },
{ "clearagain", sdl.SCANCODE_CLEARAGAIN },
{ "crsel", sdl.SCANCODE_CRSEL },
{ "exsel", sdl.SCANCODE_EXSEL },
{ "kp00", sdl.SCANCODE_KP_00 },
{ "kp000", sdl.SCANCODE_KP_000 },
{ "thsousandsseparator", sdl.SCANCODE_THOUSANDSSEPARATOR },
{ "decimalseparator", sdl.SCANCODE_DECIMALSEPARATOR },
{ "currencyunit", sdl.SCANCODE_CURRENCYUNIT },
{ "currencysubunit", sdl.SCANCODE_CURRENCYSUBUNIT },
{ "kp(", sdl.SCANCODE_KP_LEFTPAREN },
{ "kp)", sdl.SCANCODE_KP_RIGHTPAREN },
{ "kp{", sdl.SCANCODE_KP_LEFTBRACE },
{ "kp}", sdl.SCANCODE_KP_RIGHTBRACE },
{ "kptab", sdl.SCANCODE_KP_TAB },
{ "kpbackspace", sdl.SCANCODE_KP_BACKSPACE },
{ "kpa", sdl.SCANCODE_KP_A },
{ "kpb", sdl.SCANCODE_KP_B },
{ "kpc", sdl.SCANCODE_KP_C },
{ "kpd", sdl.SCANCODE_KP_D },
{ "kpe", sdl.SCANCODE_KP_E },
{ "kpf", sdl.SCANCODE_KP_F },
{ "kpxor", sdl.SCANCODE_KP_XOR },
{ "kpower", sdl.SCANCODE_KP_POWER },
{ "kp%", sdl.SCANCODE_KP_PERCENT },
{ "kp<", sdl.SCANCODE_KP_LESS },
{ "kp>", sdl.SCANCODE_KP_GREATER },
{ "kp&", sdl.SCANCODE_KP_AMPERSAND },
{ "kp&&", sdl.SCANCODE_KP_DBLAMPERSAND },
{ "kp|", sdl.SCANCODE_KP_VERTICALBAR },
{ "kp||", sdl.SCANCODE_KP_DBLVERTICALBAR },
{ "kp:", sdl.SCANCODE_KP_COLON },
{ "kp#", sdl.SCANCODE_KP_HASH },
{ "kp ", sdl.SCANCODE_KP_SPACE },
{ "kp@", sdl.SCANCODE_KP_AT },
{ "kp!", sdl.SCANCODE_KP_EXCLAM },
{ "kpmemstore", sdl.SCANCODE_KP_MEMSTORE },
{ "kpmemrecall", sdl.SCANCODE_KP_MEMRECALL },
{ "kpmemclear", sdl.SCANCODE_KP_MEMCLEAR },
{ "kpmem+", sdl.SCANCODE_KP_MEMADD },
{ "kpmem-", sdl.SCANCODE_KP_MEMSUBTRACT },
{ "kpmem*", sdl.SCANCODE_KP_MEMMULTIPLY },
{ "kpmem/", sdl.SCANCODE_KP_MEMDIVIDE },
{ "kp+-", sdl.SCANCODE_KP_PLUSMINUS },
{ "kpclear", sdl.SCANCODE_KP_CLEAR },
{ "kpclearentry", sdl.SCANCODE_KP_CLEARENTRY },
{ "kpbinary", sdl.SCANCODE_KP_BINARY },
{ "kpoctal", sdl.SCANCODE_KP_OCTAL },
{ "kpdecimal", sdl.SCANCODE_KP_DECIMAL },
{ "kphex", sdl.SCANCODE_KP_HEXADECIMAL },
{ "lctrl", sdl.SCANCODE_LCTRL },
{ "lshift", sdl.SCANCODE_LSHIFT },
{ "lalt", sdl.SCANCODE_LALT },
{ "lgui", sdl.SCANCODE_LGUI },
{ "rctrl", sdl.SCANCODE_RCTRL },
{ "rshift", sdl.SCANCODE_RSHIFT },
{ "ralt", sdl.SCANCODE_RALT },
{ "rgui", sdl.SCANCODE_RGUI },
{ "mode", sdl.SCANCODE_MODE },
{ "audionext", sdl.SCANCODE_AUDIONEXT },
{ "audioprev", sdl.SCANCODE_AUDIOPREV },
{ "audiostop", sdl.SCANCODE_AUDIOSTOP },
{ "audioplay", sdl.SCANCODE_AUDIOPLAY },
{ "audiomute", sdl.SCANCODE_AUDIOMUTE },
{ "mediaselect", sdl.SCANCODE_MEDIASELECT },
{ "www", sdl.SCANCODE_WWW },
{ "mail", sdl.SCANCODE_MAIL },
{ "calculator", sdl.SCANCODE_CALCULATOR },
{ "computer", sdl.SCANCODE_COMPUTER },
{ "acsearch", sdl.SCANCODE_AC_SEARCH },
{ "achome", sdl.SCANCODE_AC_HOME },
{ "acback", sdl.SCANCODE_AC_BACK },
{ "acforward", sdl.SCANCODE_AC_FORWARD },
{ "acstop", sdl.SCANCODE_AC_STOP },
{ "acrefresh", sdl.SCANCODE_AC_REFRESH },
{ "acbookmarks", sdl.SCANCODE_AC_BOOKMARKS },
{ "brightnessdown", sdl.SCANCODE_BRIGHTNESSDOWN },
{ "brightnessup", sdl.SCANCODE_BRIGHTNESSUP },
{ "displayswitch", sdl.SCANCODE_DISPLAYSWITCH },
{ "kbdillumtoggle", sdl.SCANCODE_KBDILLUMTOGGLE },
{ "kbdillumdown", sdl.SCANCODE_KBDILLUMDOWN },
{ "kbdillumup", sdl.SCANCODE_KBDILLUMUP },
{ "eject", sdl.SCANCODE_EJECT },
{ "sleep", sdl.SCANCODE_SLEEP },
{ "app1", sdl.SCANCODE_APP1 },
{ "app2", sdl.SCANCODE_APP2 },
}
registerKeycodes {
{ "unknown", sdl.C.SDLK_UNKNOWN },
{ "return", sdl.C.SDLK_RETURN },
{ "escape", sdl.C.SDLK_ESCAPE },
{ "backspace", sdl.C.SDLK_BACKSPACE },
{ "tab", sdl.C.SDLK_TAB },
{ "space", sdl.C.SDLK_SPACE },
{ "!", sdl.C.SDLK_EXCLAIM },
{ "\"", sdl.C.SDLK_QUOTEDBL },
{ "#", sdl.C.SDLK_HASH },
{ "%", sdl.C.SDLK_PERCENT },
{ "$", sdl.C.SDLK_DOLLAR },
{ "&", sdl.C.SDLK_AMPERSAND },
{ "'", sdl.C.SDLK_QUOTE },
{ "(", sdl.C.SDLK_LEFTPAREN },
{ ")", sdl.C.SDLK_RIGHTPAREN },
{ "*", sdl.C.SDLK_ASTERISK },
{ "+", sdl.C.SDLK_PLUS },
{ ",", sdl.C.SDLK_COMMA },
{ "-", sdl.C.SDLK_MINUS },
{ ".", sdl.C.SDLK_PERIOD },
{ "/", sdl.C.SDLK_SLASH },
{ "0", sdl.C.SDLK_0 },
{ "1", sdl.C.SDLK_1 },
{ "2", sdl.C.SDLK_2 },
{ "3", sdl.C.SDLK_3 },
{ "4", sdl.C.SDLK_4 },
{ "5", sdl.C.SDLK_5 },
{ "6", sdl.C.SDLK_6 },
{ "7", sdl.C.SDLK_7 },
{ "8", sdl.C.SDLK_8 },
{ "9", sdl.C.SDLK_9 },
{ ":", sdl.C.SDLK_COLON },
{ ";", sdl.C.SDLK_SEMICOLON },
{ "<", sdl.C.SDLK_LESS },
{ "=", sdl.C.SDLK_EQUALS },
{ ">", sdl.C.SDLK_GREATER },
{ "?", sdl.C.SDLK_QUESTION },
{ "@", sdl.C.SDLK_AT },
{ "[", sdl.C.SDLK_LEFTBRACKET },
{ "\\", sdl.C.SDLK_BACKSLASH },
{ "]", sdl.C.SDLK_RIGHTBRACKET },
{ "^", sdl.C.SDLK_CARET },
{ "_", sdl.C.SDLK_UNDERSCORE },
{ "`", sdl.C.SDLK_BACKQUOTE },
{ "a", sdl.C.SDLK_a },
{ "b", sdl.C.SDLK_b },
{ "c", sdl.C.SDLK_c },
{ "d", sdl.C.SDLK_d },
{ "e", sdl.C.SDLK_e },
{ "f", sdl.C.SDLK_f },
{ "g", sdl.C.SDLK_g },
{ "h", sdl.C.SDLK_h },
{ "i", sdl.C.SDLK_i },
{ "j", sdl.C.SDLK_j },
{ "k", sdl.C.SDLK_k },
{ "l", sdl.C.SDLK_l },
{ "m", sdl.C.SDLK_m },
{ "n", sdl.C.SDLK_n },
{ "o", sdl.C.SDLK_o },
{ "p", sdl.C.SDLK_p },
{ "q", sdl.C.SDLK_q },
{ "r", sdl.C.SDLK_r },
{ "s", sdl.C.SDLK_s },
{ "t", sdl.C.SDLK_t },
{ "u", sdl.C.SDLK_u },
{ "v", sdl.C.SDLK_v },
{ "w", sdl.C.SDLK_w },
{ "x", sdl.C.SDLK_x },
{ "y", sdl.C.SDLK_y },
{ "z", sdl.C.SDLK_z },
{ "capslock", sdl.C.SDLK_CAPSLOCK },
{ "f1", sdl.C.SDLK_F1 },
{ "f2", sdl.C.SDLK_F2 },
{ "f3", sdl.C.SDLK_F3 },
{ "f4", sdl.C.SDLK_F4 },
{ "f5", sdl.C.SDLK_F5 },
{ "f6", sdl.C.SDLK_F6 },
{ "f7", sdl.C.SDLK_F7 },
{ "f8", sdl.C.SDLK_F8 },
{ "f9", sdl.C.SDLK_F9 },
{ "f10", sdl.C.SDLK_F10 },
{ "f11", sdl.C.SDLK_F11 },
{ "f12", sdl.C.SDLK_F12 },
{ "printscreen", sdl.C.SDLK_PRINTSCREEN },
{ "scrolllock", sdl.C.SDLK_SCROLLLOCK },
{ "pause", sdl.C.SDLK_PAUSE },
{ "insert", sdl.C.SDLK_INSERT },
{ "home", sdl.C.SDLK_HOME },
{ "pageup", sdl.C.SDLK_PAGEUP },
{ "delete", sdl.C.SDLK_DELETE },
{ "end", sdl.C.SDLK_END },
{ "pagedown", sdl.C.SDLK_PAGEDOWN },
{ "right", sdl.C.SDLK_RIGHT },
{ "left", sdl.C.SDLK_LEFT },
{ "down", sdl.C.SDLK_DOWN },
{ "up", sdl.C.SDLK_UP },
{ "numlock", sdl.C.SDLK_NUMLOCKCLEAR },
{ "kp/", sdl.C.SDLK_KP_DIVIDE },
{ "kp*", sdl.C.SDLK_KP_MULTIPLY },
{ "kp-", sdl.C.SDLK_KP_MINUS },
{ "kp+", sdl.C.SDLK_KP_PLUS },
{ "kpenter", sdl.C.SDLK_KP_ENTER },
{ "kp0", sdl.C.SDLK_KP_0 },
{ "kp1", sdl.C.SDLK_KP_1 },
{ "kp2", sdl.C.SDLK_KP_2 },
{ "kp3", sdl.C.SDLK_KP_3 },
{ "kp4", sdl.C.SDLK_KP_4 },
{ "kp5", sdl.C.SDLK_KP_5 },
{ "kp6", sdl.C.SDLK_KP_6 },
{ "kp7", sdl.C.SDLK_KP_7 },
{ "kp8", sdl.C.SDLK_KP_8 },
{ "kp9", sdl.C.SDLK_KP_9 },
{ "kp.", sdl.C.SDLK_KP_PERIOD },
{ "kp,", sdl.C.SDLK_KP_COMMA },
{ "kp=", sdl.C.SDLK_KP_EQUALS },
{ "application", sdl.C.SDLK_APPLICATION },
{ "power", sdl.C.SDLK_POWER },
{ "f13", sdl.C.SDLK_F13 },
{ "f14", sdl.C.SDLK_F14 },
{ "f15", sdl.C.SDLK_F15 },
{ "f16", sdl.C.SDLK_F16 },
{ "f17", sdl.C.SDLK_F17 },
{ "f18", sdl.C.SDLK_F18 },
{ "f19", sdl.C.SDLK_F19 },
{ "f20", sdl.C.SDLK_F20 },
{ "f21", sdl.C.SDLK_F21 },
{ "f22", sdl.C.SDLK_F22 },
{ "f23", sdl.C.SDLK_F23 },
{ "f24", sdl.C.SDLK_F24 },
{ "execute", sdl.C.SDLK_EXECUTE },
{ "help", sdl.C.SDLK_HELP },
{ "menu", sdl.C.SDLK_MENU },
{ "select", sdl.C.SDLK_SELECT },
{ "stop", sdl.C.SDLK_STOP },
{ "again", sdl.C.SDLK_AGAIN },
{ "undo", sdl.C.SDLK_UNDO },
{ "cut", sdl.C.SDLK_CUT },
{ "copy", sdl.C.SDLK_COPY },
{ "paste", sdl.C.SDLK_PASTE },
{ "find", sdl.C.SDLK_FIND },
{ "mute", sdl.C.SDLK_MUTE },
{ "volumeup", sdl.C.SDLK_VOLUMEUP },
{ "volumedown", sdl.C.SDLK_VOLUMEDOWN },
{ "alterase", sdl.C.SDLK_ALTERASE },
{ "sysreq", sdl.C.SDLK_SYSREQ },
{ "cancel", sdl.C.SDLK_CANCEL },
{ "clear", sdl.C.SDLK_CLEAR },
{ "prior", sdl.C.SDLK_PRIOR },
{ "return2", sdl.C.SDLK_RETURN2 },
{ "separator", sdl.C.SDLK_SEPARATOR },
{ "out", sdl.C.SDLK_OUT },
{ "oper", sdl.C.SDLK_OPER },
{ "clearagain", sdl.C.SDLK_CLEARAGAIN },
{ "thsousandsseparator", sdl.C.SDLK_THOUSANDSSEPARATOR },
{ "decimalseparator", sdl.C.SDLK_DECIMALSEPARATOR },
{ "currencyunit", sdl.C.SDLK_CURRENCYUNIT },
{ "currencysubunit", sdl.C.SDLK_CURRENCYSUBUNIT },
{ "lctrl", sdl.C.SDLK_LCTRL },
{ "lshift", sdl.C.SDLK_LSHIFT },
{ "lalt", sdl.C.SDLK_LALT },
{ "lgui", sdl.C.SDLK_LGUI },
{ "rctrl", sdl.C.SDLK_RCTRL },
{ "rshift", sdl.C.SDLK_RSHIFT },
{ "ralt", sdl.C.SDLK_RALT },
{ "rgui", sdl.C.SDLK_RGUI },
{ "mode", sdl.C.SDLK_MODE },
{ "audionext", sdl.C.SDLK_AUDIONEXT },
{ "audioprev", sdl.C.SDLK_AUDIOPREV },
{ "audiostop", sdl.C.SDLK_AUDIOSTOP },
{ "audioplay", sdl.C.SDLK_AUDIOPLAY },
{ "audiomute", sdl.C.SDLK_AUDIOMUTE },
{ "mediaselect", sdl.C.SDLK_MEDIASELECT },
{ "www", sdl.C.SDLK_WWW },
{ "mail", sdl.C.SDLK_MAIL },
{ "calculator", sdl.C.SDLK_CALCULATOR },
{ "computer", sdl.C.SDLK_COMPUTER },
{ "appsearch", sdl.C.SDLK_AC_SEARCH },
{ "apphome", sdl.C.SDLK_AC_HOME },
{ "appback", sdl.C.SDLK_AC_BACK },
{ "appforward", sdl.C.SDLK_AC_FORWARD },
{ "appstop", sdl.C.SDLK_AC_STOP },
{ "apprefresh", sdl.C.SDLK_AC_REFRESH },
{ "appbookmarks", sdl.C.SDLK_AC_BOOKMARKS },
{ "brightnessdown", sdl.C.SDLK_BRIGHTNESSDOWN },
{ "brightnessup", sdl.C.SDLK_BRIGHTNESSUP },
{ "displayswitch", sdl.C.SDLK_DISPLAYSWITCH },
{ "kbdillumtoggle", sdl.C.SDLK_KBDILLUMTOGGLE },
{ "kbdillumdown", sdl.C.SDLK_KBDILLUMDOWN },
{ "kbdillumup", sdl.C.SDLK_KBDILLUMUP },
{ "eject", sdl.C.SDLK_EJECT },
{ "sleep", sdl.C.SDLK_SLEEP },
}
return Keyboard

Binary file not shown.

View File

@@ -0,0 +1,67 @@
local ROOT = (...):gsub('[^.]*$', '')
local ffi = require 'ffi'
local sdl = require(ROOT .. 'sdl2.init')
sdl.AudioCVT = ffi.typeof 'SDL_AudioCVT'
-- sdl.AudioDeviceEvent = ffi.typeof 'SDL_AudioDeviceEvent'
sdl.AudioSpec = ffi.typeof 'SDL_AudioSpec'
sdl.Color = ffi.typeof 'SDL_Color'
sdl.ControllerAxisEvent = ffi.typeof 'SDL_ControllerAxisEvent'
sdl.ControllerButtonEvent = ffi.typeof 'SDL_ControllerButtonEvent'
sdl.ControllerDeviceEvent = ffi.typeof 'SDL_ControllerDeviceEvent'
sdl.DisplayMode = ffi.typeof 'SDL_DisplayMode'
sdl.DollarGestureEvent = ffi.typeof 'SDL_DollarGestureEvent'
sdl.DropEvent = ffi.typeof 'SDL_DropEvent'
sdl.Event = ffi.typeof 'SDL_Event'
sdl.Finger = ffi.typeof 'SDL_Finger'
sdl.HapticCondition = ffi.typeof 'SDL_HapticCondition'
sdl.HapticConstant = ffi.typeof 'SDL_HapticConstant'
sdl.HapticCustom = ffi.typeof 'SDL_HapticCustom'
sdl.HapticDirection = ffi.typeof 'SDL_HapticDirection'
sdl.HapticEffect = ffi.typeof 'SDL_HapticEffect'
sdl.HapticLeftRight = ffi.typeof 'SDL_HapticLeftRight'
sdl.HapticPeriodic = ffi.typeof 'SDL_HapticPeriodic'
sdl.HapticRamp = ffi.typeof 'SDL_HapticRamp'
sdl.JoyAxisEvent = ffi.typeof 'SDL_JoyAxisEvent'
sdl.JoyBallEvent = ffi.typeof 'SDL_JoyBallEvent'
sdl.JoyButtonEvent = ffi.typeof 'SDL_JoyButtonEvent'
sdl.JoyDeviceEvent = ffi.typeof 'SDL_JoyDeviceEvent'
sdl.JoyHatEvent = ffi.typeof 'SDL_JoyHatEvent'
sdl.KeyboardEvent = ffi.typeof 'SDL_KeyboardEvent'
sdl.Keysym = ffi.typeof 'SDL_Keysym'
sdl.MessageBoxButtonData = ffi.typeof 'SDL_MessageBoxButtonData'
sdl.MessageBoxColor = ffi.typeof 'SDL_MessageBoxColor'
sdl.MessageBoxColorScheme = ffi.typeof 'SDL_MessageBoxColorScheme'
sdl.MessageBoxData = ffi.typeof 'SDL_MessageBoxData'
sdl.MouseButtonEvent = ffi.typeof 'SDL_MouseButtonEvent'
sdl.MouseMotionEvent = ffi.typeof 'SDL_MouseMotionEvent'
sdl.MouseWheelEvent = ffi.typeof 'SDL_MouseWheelEvent'
sdl.MultiGestureEvent = ffi.typeof 'SDL_MultiGestureEvent'
sdl.Palette = ffi.typeof 'SDL_Palette'
sdl.PixelFormat = ffi.typeof 'SDL_PixelFormat'
sdl.Point = ffi.typeof 'SDL_Point'
sdl.QuitEvent = ffi.typeof 'SDL_QuitEvent'
sdl.RWops = ffi.typeof 'SDL_RWops'
sdl.Rect = ffi.typeof 'SDL_Rect'
sdl.RendererInfo = ffi.typeof 'SDL_RendererInfo'
sdl.Surface = ffi.typeof 'SDL_Surface'
sdl.SysWMEvent = ffi.typeof 'SDL_SysWMEvent'
-- sdl.SysWMinfo = ffi.typeof 'SDL_SysWMinfo'
sdl.SysWMmsg = ffi.typeof 'SDL_SysWMmsg'
sdl.TextEditingEvent = ffi.typeof 'SDL_TextEditingEvent'
sdl.TextInputEvent = ffi.typeof 'SDL_TextInputEvent'
sdl.Texture = ffi.typeof 'SDL_Texture'
sdl.TouchFingerEvent = ffi.typeof 'SDL_TouchFingerEvent'
sdl.UserEvent = ffi.typeof 'SDL_UserEvent'
sdl.WindowEvent = ffi.typeof 'SDL_WindowEvent'
sdl.assert_data = ffi.typeof 'SDL_assert_data'
sdl.atomic_t = ffi.typeof 'SDL_atomic_t'
sdl.version = ffi.typeof 'SDL_version'
if sdl.init(sdl.INIT_VIDEO) ~= 0 then
io.stderr:write(ffi.string(sdl.getError()))
os.exit(1)
end
return sdl

View File

@@ -0,0 +1,36 @@
Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert)
Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu)
Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu)
Copyright (c) 2011-2013 NYU (Clement Farabet)
Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston)
Copyright (c) 2006 Idiap Research Institute (Samy Bengio)
Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the names of Deepmind Technologies, NYU, NEC Laboratories America
and IDIAP Research Institute nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,32 @@
sdl2-ffi
========
A LuaJIT interface to SDL2
# Installation #
First, make sure SDL2 is installed on your system. This package only requires the binary shared libraries (.so, .dylib, .dll).
Please see your package management system to install SDL2. You can also download yourself binaries on the
[SDL2 web page](http://libsdl.org/download-2.0.php)
```sh
luarocks install https://raw.github.com/torch/sdl2-ffi/master/rocks/sdl2-scm-1.rockspec
```
*Note*: this SDL interface supports only SDL2, not SDL 1.2.
# Usage #
```lua
local sdl = require 'sdl2'
sdl.init(sdl.INIT_VIDEO)
...
```
All SDL C functions are available in the `sdl` namespace returned by require. The only difference is the naming, which is not prefixed
by `SDL_` anymore. The same goes for all C defines (like `SDL_INIT_VIDEO`, which can now be accessed with `sdl.INIT_VIDEO`).
Although the interface is quite complete, there are still few defines not ported in this package. Fill free to post a message about it,
or to request pulls.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
-- Function definitions which were not output by
-- the C preprocessor
local sdl
local function registerdefines(sdl)
-- audio
function sdl.AUDIO_BITSIZE(x)
return bit.band(x, sdl.AUDIO_MASK_BITSIZE)
end
function sdl.AUDIO_ISFLOAT(x)
return bit.band(x, sdl.AUDIO_MASK_DATATYPE) ~= 0
end
function sdl.AUDIO_ISBIGENDIAN(x)
return bit.band(x, sdl.AUDIO_MASK_ENDIAN) ~= 0
end
function sdl.AUDIO_ISSIGNED(x)
return bit.band(x, sdl.AUDIO_MASK_SIGNED) ~= 0
end
function sdl.AUDIO_ISINT(x)
return not sdl.AUDIO_ISFLOAT(x)
end
function sdl.AUDIO_ISLITTLEENDIAN(x)
return not sdl.AUDIO_ISBIGENDIAN(x)
end
function sdl.AUDIO_ISUNSIGNED(x)
return not sdl.AUDIO_ISSIGNED(x)
end
function sdl.loadWAV(file, spec, audio_buf, audio_len)
return sdl.loadWAV_RW(sdl.RWFromFile(file, "rb"), 1, spec, audio_buf, audio_len)
end
-- surface
sdl.blitSurface = sdl.upperBlit
function sdl.MUSTLOCK(S)
return bit.band(S.flags, sdl.RLEACCEL)
end
function sdl.loadBMP(file)
return sdl.loadBMP_RW(sdl.RWFromFile(file, 'rb'), 1)
end
function sdl.saveBMP(surface, file)
return sdl.saveBMP_RW(surface, sdl.RWFromFile(file, 'wb'), 1)
end
end
return registerdefines

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
local REL = (...):gsub('[^.]*$', '')
local sdl = require(REL .. 'sdl')
local SpriteBatch = setmetatable({}, { __call = function (self, ...)
local object = setmetatable({}, { __index = self })
return object, self.constructor(object, ...)
end })
--[[
spriteBatch = SpriteBatch( image, size )
Arguments
Image image
The Image to use for the sprites.
number size (1000)
The max number of sprites.
Returns
SpriteBatch spriteBatch
The new SpriteBatch.
--]]
function SpriteBatch:constructor (image)
self.image = image
self.sprites = {}
end
--[[
id = SpriteBatch:add( quad, x, y, r, sx, sy )
Arguments
Quad quad
The Quad to add.
number x
The position to draw the object (x-axis).
number y
The position to draw the object (y-axis).
number r (0)
Orientation (radians). (not implemented)
number sx (1)
Scale factor (x-axis).
number sy (sx)
Scale factor (y-axis).
Returns
number id
An identifier for the added sprite.
--]]
function SpriteBatch:add (quad, x, y, r, sx, sy)
local sprites = self.sprites
sprites[#sprites + 1] = { quad = quad, x = x, y = y,
sx = sx or 1, sy = sy or 1 }
end
function SpriteBatch:draw ()
local image = self.image
local renderer = image.sdlRenderer
local texture = image.sdlTexture
for _, sprite in ipairs(self.sprites) do
local quad = sprite.quad
local w = math.ceil(quad[3] * sprite.sx)
local h = math.ceil(quad[4] * sprite.sy)
local src = sdl.Rect(quad)
local dst = sdl.Rect(sprite.x, sprite.y, w, h)
sdl.renderCopy(renderer, texture, src, dst)
end
end
return SpriteBatch

133
luigi/backend/love.lua Normal file
View File

@@ -0,0 +1,133 @@
local ROOT = (...):gsub('[^.]*.[^.]*$', '')
local Base = require(ROOT .. 'base')
local Hooker = require(ROOT .. 'hooker')
local Backend = {}
Backend.run = function () end
Backend.Cursor = love.mouse.newCursor
Backend.Font = require(ROOT .. 'backend.love.font')
Backend.Image = love.graphics.newImage
Backend.Quad = love.graphics.newQuad
Backend.SpriteBatch = love.graphics.newSpriteBatch
Backend.draw = love.graphics.draw
Backend.drawRectangle = love.graphics.rectangle
Backend.print = love.graphics.print
Backend.printf = love.graphics.printf
Backend.getClipboardText = love.system.getClipboardText
Backend.setClipboardText = love.system.setClipboardText
Backend.getMousePosition = love.mouse.getPosition
Backend.getMousePosition = love.mouse.getPosition
Backend.getSystemCursor = love.mouse.getSystemCursor
Backend.getWindowSize = function ()
return love.graphics.getWidth(), love.graphics.getHeight()
end
Backend.getTime = love.timer.getTime
Backend.isKeyDown = love.keyboard.isDown
Backend.isMouseDown = love.mouse.isDown
Backend.pop = love.graphics.pop
local push = love.graphics.push
Backend.push = function ()
return push 'all'
end
Backend.quit = love.event.quit
Backend.setColor = love.graphics.setColor
Backend.setCursor = love.mouse.setCursor
Backend.setFont = function (font)
return love.graphics.setFont(font.loveFont)
end
Backend.setScissor = love.graphics.setScissor
function Backend.hide (layout)
for _, item in ipairs(layout.hooks) do
Hooker.unhook(item)
end
layout.hooks = {}
end
local function hook (layout, key, method, hookLast)
layout.hooks[#layout.hooks + 1] = Hooker.hook(love, key, method, hookLast)
end
local getMouseButtonId, isMouseDown
if love._version_minor < 10 then
getMouseButtonId = function (value)
return value == 'l' and 1
or value == 'r' and 2
or value == 'm' and 3
end
isMouseDown = function ()
return love.mouse.isDown('l', 'r', 'm')
end
else
getMouseButtonId = function (value)
return value
end
isMouseDown = function ()
return love.mouse.isDown(1, 2, 3)
end
end
function Backend.show (layout)
local input = layout.input
hook(layout, 'draw', function ()
input:handleDisplay(layout)
end, true)
hook(layout, 'resize', function (width, height)
return input:handleReshape(layout, width, height)
end)
hook(layout, 'mousepressed', function (x, y, button)
return input:handlePressStart(layout, getMouseButtonId(button), x, y)
end)
hook(layout, 'mousereleased', function (x, y, button)
return input:handlePressEnd(layout, getMouseButtonId(button), x, y)
end)
hook(layout, 'mousemoved', function (x, y, dx, dy)
if isMouseDown() then
return input:handlePressedMove(layout, x, y)
else
return input:handleMove(layout, x, y)
end
end)
hook(layout, 'keypressed', function (key, isRepeat)
return input:handleKeyPress(layout, key, Backend.getMousePosition())
end)
hook(layout, 'keyreleased', function (key)
return input:handleKeyRelease(layout, key, Backend.getMousePosition())
end)
hook(layout, 'textinput', function (text)
return input:handleTextInput(layout, text, Backend.getMousePosition())
end)
end
return Backend

View File

@@ -0,0 +1,65 @@
local Font = setmetatable({}, { __call = function (self, ...)
local object = setmetatable({}, { __index = self })
return object, self.constructor(object, ...)
end })
local fontCache = {}
function Font:constructor (path, size, color)
if not size then
size = 12
end
if not color then
color = { 0, 0, 0 }
end
local key = (path or '') .. '_' .. size
if not fontCache[key] then
if path then
fontCache[key] = love.graphics.newFont(path, size)
else
fontCache[key] = love.graphics.newFont(size)
end
end
self.loveFont = fontCache[key]
self.color = color
end
function Font:setAlignment (align)
self.align = align
end
function Font:setWidth (width)
self.width = width
end
function Font:getLineHeight ()
return self.loveFont:getHeight()
end
function Font:getAscender ()
return self.loveFont:getAscent()
end
function Font:getDescender ()
return self.loveFont:getDescent()
end
function Font:getAdvance (text)
return (self.loveFont:getWidth(text))
end
if love._version_minor < 10 then
function Font:getWrappedHeight (text)
local _, lines = self.loveFont:getWrap(text, self.width)
return lines * self.loveFont:getHeight()
end
else
function Font:getWrappedHeight (text)
local _, lines = self.loveFont:getWrap(text, self.width)
return #lines * self.loveFont:getHeight()
end
end
return Font