forked from len0rd/rockbox
Lua: add image handling + some other wrappers
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21063 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
ce7738e617
commit
86fe1e8b5c
1 changed files with 281 additions and 1 deletions
|
@ -38,6 +38,136 @@
|
|||
* and returns the number of results. Any other value in the stack below the results will be properly
|
||||
* discarded by Lua. Like a Lua function, a C function called by Lua can also return many results.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* -----------------------------
|
||||
*
|
||||
* Rockbox Lua image wrapper
|
||||
*
|
||||
* -----------------------------
|
||||
*/
|
||||
|
||||
#define ROCKLUA_IMAGE "rb.image"
|
||||
struct rocklua_image
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
fb_data *data;
|
||||
};
|
||||
|
||||
static void rli_wrap(lua_State *L, fb_data *src, int width, int height)
|
||||
{
|
||||
struct rocklua_image *a = (struct rocklua_image *)lua_newuserdata(L, sizeof(struct rocklua_image));
|
||||
|
||||
luaL_getmetatable(L, ROCKLUA_IMAGE);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
a->width = width;
|
||||
a->height = height;
|
||||
a->data = src;
|
||||
}
|
||||
|
||||
static int rli_new(lua_State *L)
|
||||
{
|
||||
int width = luaL_checkint(L, 1);
|
||||
int height = luaL_checkint(L, 2);
|
||||
size_t nbytes = sizeof(struct rocklua_image) + (width - 1)*(height - 1)*sizeof(fb_data);
|
||||
struct rocklua_image *a = (struct rocklua_image *)lua_newuserdata(L, nbytes);
|
||||
|
||||
luaL_getmetatable(L, ROCKLUA_IMAGE);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
a->width = width;
|
||||
a->height = height;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct rocklua_image* rli_checktype(lua_State *L, int arg)
|
||||
{
|
||||
void *ud = luaL_checkudata(L, arg, ROCKLUA_IMAGE);
|
||||
luaL_argcheck(L, ud != NULL, arg, "'" ROCKLUA_IMAGE "' expected");
|
||||
return (struct rocklua_image*) ud;
|
||||
}
|
||||
|
||||
static int rli_width(lua_State *L)
|
||||
{
|
||||
struct rocklua_image *a = rli_checktype(L, 1);
|
||||
lua_pushnumber(L, a->width);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rli_height(lua_State *L)
|
||||
{
|
||||
struct rocklua_image *a = rli_checktype(L, 1);
|
||||
lua_pushnumber(L, a->height);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static fb_data* rli_element(lua_State *L)
|
||||
{
|
||||
struct rocklua_image *a = rli_checktype(L, 1);
|
||||
int x = luaL_checkint(L, 2);
|
||||
int y = luaL_checkint(L, 3);
|
||||
|
||||
luaL_argcheck(L, 1 <= x && x <= a->width, 2,
|
||||
"index out of range");
|
||||
luaL_argcheck(L, 1 <= y && y <= a->height, 3,
|
||||
"index out of range");
|
||||
|
||||
/* return element address */
|
||||
return &a->data[a->height * (y - 1) + (x - 1)];
|
||||
}
|
||||
|
||||
static int rli_set(lua_State *L)
|
||||
{
|
||||
fb_data newvalue = (fb_data) luaL_checknumber(L, 4);
|
||||
*rli_element(L) = newvalue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rli_get(lua_State *L)
|
||||
{
|
||||
lua_pushnumber(L, *rli_element(L));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rli_tostring(lua_State *L)
|
||||
{
|
||||
struct rocklua_image *a = rli_checktype(L, 1);
|
||||
lua_pushfstring(L, ROCKLUA_IMAGE ": %dx%d", a->width, a->height);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_reg rli_lib [] =
|
||||
{
|
||||
{"__tostring", rli_tostring},
|
||||
{"set", rli_set},
|
||||
{"get", rli_get},
|
||||
{"width", rli_width},
|
||||
{"height", rli_height},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static inline void rli_init(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, ROCKLUA_IMAGE);
|
||||
|
||||
lua_pushstring(L, "__index");
|
||||
lua_pushvalue(L, -2); /* pushes the metatable */
|
||||
lua_settable(L, -3); /* metatable.__index = metatable */
|
||||
|
||||
luaL_register(L, NULL, rli_lib);
|
||||
}
|
||||
|
||||
/*
|
||||
* -----------------------------
|
||||
*
|
||||
* Rockbox wrappers start here!
|
||||
*
|
||||
* -----------------------------
|
||||
*/
|
||||
|
||||
#define RB_WRAP(M) static int rock_##M(lua_State *L)
|
||||
|
||||
RB_WRAP(splash)
|
||||
|
@ -55,6 +185,16 @@ RB_WRAP(lcd_update)
|
|||
return 0;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_update_rect)
|
||||
{
|
||||
int x = luaL_checkint(L, 1);
|
||||
int y = luaL_checkint(L, 2);
|
||||
int width = luaL_checkint(L, 3);
|
||||
int height = luaL_checkint(L, 4);
|
||||
rb->lcd_update_rect(x, y, width, height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_clear_display)
|
||||
{
|
||||
(void)L;
|
||||
|
@ -97,6 +237,12 @@ RB_WRAP(lcd_stop_scroll)
|
|||
}
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
RB_WRAP(lcd_framebuffer)
|
||||
{
|
||||
rli_wrap(L, rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_set_drawmode)
|
||||
{
|
||||
int drawmode = luaL_checkint(L, 1);
|
||||
|
@ -179,7 +325,106 @@ RB_WRAP(lcd_fillrect)
|
|||
rb->lcd_fillrect(x, y, width, height);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LCD_DEPTH > 1
|
||||
RB_WRAP(lcd_set_foreground)
|
||||
{
|
||||
unsigned foreground = luaL_checkint(L, 1);
|
||||
rb->lcd_set_foreground(foreground);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_get_foreground)
|
||||
{
|
||||
unsigned result = rb->lcd_get_foreground();
|
||||
lua_pushinteger(L, result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_set_background)
|
||||
{
|
||||
unsigned background = luaL_checkint(L, 1);
|
||||
rb->lcd_set_background(background);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_get_background)
|
||||
{
|
||||
unsigned result = rb->lcd_get_background();
|
||||
lua_pushinteger(L, result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_bitmap_part)
|
||||
{
|
||||
struct rocklua_image *src = rli_checktype(L, 1);
|
||||
int src_x = luaL_checkint(L, 2);
|
||||
int src_y = luaL_checkint(L, 3);
|
||||
int stride = luaL_checkint(L, 4);
|
||||
int x = luaL_checkint(L, 5);
|
||||
int y = luaL_checkint(L, 6);
|
||||
int width = luaL_checkint(L, 7);
|
||||
int height = luaL_checkint(L, 8);
|
||||
|
||||
rb->lcd_bitmap_part(src->data, src_x, src_y, stride, x, y, width, height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_bitmap)
|
||||
{
|
||||
struct rocklua_image *src = rli_checktype(L, 1);
|
||||
int x = luaL_checkint(L, 2);
|
||||
int y = luaL_checkint(L, 3);
|
||||
int width = luaL_checkint(L, 4);
|
||||
int height = luaL_checkint(L, 5);
|
||||
|
||||
rb->lcd_bitmap(src->data, x, y, width, height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_get_backdrop)
|
||||
{
|
||||
fb_data* backdrop = rb->lcd_get_backdrop();
|
||||
if(backdrop == NULL)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
rli_wrap(L, backdrop, LCD_WIDTH, LCD_HEIGHT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif /* LCD_DEPTH > 1 */
|
||||
|
||||
#if LCD_DEPTH == 16
|
||||
RB_WRAP(lcd_bitmap_transparent_part)
|
||||
{
|
||||
struct rocklua_image *src = rli_checktype(L, 1);
|
||||
int src_x = luaL_checkint(L, 2);
|
||||
int src_y = luaL_checkint(L, 3);
|
||||
int stride = luaL_checkint(L, 4);
|
||||
int x = luaL_checkint(L, 5);
|
||||
int y = luaL_checkint(L, 6);
|
||||
int width = luaL_checkint(L, 7);
|
||||
int height = luaL_checkint(L, 8);
|
||||
|
||||
rb->lcd_bitmap_transparent_part(src->data, src_x, src_y, stride, x, y, width, height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RB_WRAP(lcd_bitmap_transparent)
|
||||
{
|
||||
struct rocklua_image *src = rli_checktype(L, 1);
|
||||
int x = luaL_checkint(L, 2);
|
||||
int y = luaL_checkint(L, 3);
|
||||
int width = luaL_checkint(L, 4);
|
||||
int height = luaL_checkint(L, 5);
|
||||
|
||||
rb->lcd_bitmap_transparent(src->data, x, y, width, height);
|
||||
return 0;
|
||||
}
|
||||
#endif /* LCD_DEPTH == 16 */
|
||||
|
||||
#endif /* defined(LCD_BITMAP) */
|
||||
|
||||
RB_WRAP(yield)
|
||||
{
|
||||
|
@ -432,18 +677,34 @@ RB_WRAP(file_exists)
|
|||
return 1;
|
||||
}
|
||||
|
||||
RB_WRAP(font_getstringsize)
|
||||
{
|
||||
const unsigned char* str = luaL_checkstring(L, 1);
|
||||
int fontnumber = luaL_checkint(L, 2);
|
||||
int w, h;
|
||||
|
||||
int result = rb->font_getstringsize(str, &w, &h, fontnumber);
|
||||
lua_pushinteger(L, result);
|
||||
lua_pushinteger(L, w);
|
||||
lua_pushinteger(L, h);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
#define R(NAME) {#NAME, rock_##NAME}
|
||||
static const luaL_Reg rocklib[] =
|
||||
{
|
||||
/* Graphics */
|
||||
R(lcd_clear_display),
|
||||
R(lcd_update),
|
||||
R(lcd_update_rect),
|
||||
R(lcd_puts),
|
||||
R(lcd_putsxy),
|
||||
R(lcd_puts_scroll),
|
||||
R(lcd_stop_scroll),
|
||||
R(splash),
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
R(lcd_framebuffer),
|
||||
R(lcd_set_drawmode),
|
||||
R(lcd_get_drawmode),
|
||||
R(lcd_setfont),
|
||||
|
@ -453,6 +714,19 @@ static const luaL_Reg rocklib[] =
|
|||
R(lcd_vline),
|
||||
R(lcd_drawrect),
|
||||
R(lcd_fillrect),
|
||||
#if LCD_DEPTH > 1
|
||||
R(lcd_set_foreground),
|
||||
R(lcd_get_foreground),
|
||||
R(lcd_set_background),
|
||||
R(lcd_get_background),
|
||||
R(lcd_get_backdrop),
|
||||
R(lcd_bitmap_part),
|
||||
R(lcd_bitmap),
|
||||
#endif
|
||||
#if LCD_DEPTH == 16
|
||||
R(lcd_bitmap_transparent_part),
|
||||
R(lcd_bitmap_transparent),
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* File handling */
|
||||
|
@ -498,6 +772,10 @@ static const luaL_Reg rocklib[] =
|
|||
R(backlight_set_brightness),
|
||||
#endif
|
||||
|
||||
R(font_getstringsize),
|
||||
|
||||
{"new_image", rli_new},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
#undef R
|
||||
|
@ -525,6 +803,8 @@ LUALIB_API int luaopen_rock(lua_State *L)
|
|||
RB_CONSTANT(SEEK_CUR);
|
||||
RB_CONSTANT(SEEK_END);
|
||||
|
||||
rli_init(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue