mirror of
https://github.com/airstruck/luigi.git
synced 2025-12-18 18:06:44 +00:00
add dedicated backend (WIP)
This commit is contained in:
288
luigi/backend/ffisdl.lua
Normal file
288
luigi/backend/ffisdl.lua
Normal 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
|
||||
270
luigi/backend/ffisdl/font.lua
Normal file
270
luigi/backend/ffisdl/font.lua
Normal 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
|
||||
46
luigi/backend/ffisdl/image.lua
Normal file
46
luigi/backend/ffisdl/image.lua
Normal 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
|
||||
494
luigi/backend/ffisdl/keyboard.lua
Normal file
494
luigi/backend/ffisdl/keyboard.lua
Normal 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
|
||||
BIN
luigi/backend/ffisdl/resource/DejaVuSans.ttf
Normal file
BIN
luigi/backend/ffisdl/resource/DejaVuSans.ttf
Normal file
Binary file not shown.
67
luigi/backend/ffisdl/sdl.lua
Normal file
67
luigi/backend/ffisdl/sdl.lua
Normal 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
|
||||
36
luigi/backend/ffisdl/sdl2/LICENSE
Normal file
36
luigi/backend/ffisdl/sdl2/LICENSE
Normal 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.
|
||||
32
luigi/backend/ffisdl/sdl2/README.md
Normal file
32
luigi/backend/ffisdl/sdl2/README.md
Normal 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.
|
||||
|
||||
|
||||
2599
luigi/backend/ffisdl/sdl2/cdefs.lua
Normal file
2599
luigi/backend/ffisdl/sdl2/cdefs.lua
Normal file
File diff suppressed because it is too large
Load Diff
58
luigi/backend/ffisdl/sdl2/defines.lua
Normal file
58
luigi/backend/ffisdl/sdl2/defines.lua
Normal 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
|
||||
1500
luigi/backend/ffisdl/sdl2/init.lua
Normal file
1500
luigi/backend/ffisdl/sdl2/init.lua
Normal file
File diff suppressed because it is too large
Load Diff
75
luigi/backend/ffisdl/spritebatch.lua
Normal file
75
luigi/backend/ffisdl/spritebatch.lua
Normal 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
133
luigi/backend/love.lua
Normal 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
|
||||
65
luigi/backend/love/font.lua
Normal file
65
luigi/backend/love/font.lua
Normal 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
|
||||
Reference in New Issue
Block a user