diff --git a/libs/sf2dlib/libsf2d/source/sf2d.c b/libs/sf2dlib/libsf2d/source/sf2d.c index 0c23c65..6f564fa 100644 --- a/libs/sf2dlib/libsf2d/source/sf2d.c +++ b/libs/sf2dlib/libsf2d/source/sf2d.c @@ -151,7 +151,7 @@ void sf2d_start_frame(gfxScreen_t screen, gfx3dSide_t side) GPU_DepthMap(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_NONE); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); - GPU_SetStencilOp(GPU_KEEP, GPU_KEEP, GPU_KEEP); + GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP); GPU_SetBlendingColor(0,0,0,0); GPU_SetDepthTestAndWriteMask(true, GPU_GEQUAL, GPU_WRITE_ALL); GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); diff --git a/libs/sf2dlib/libsf2d/source/sf2d_texture.c b/libs/sf2dlib/libsf2d/source/sf2d_texture.c index c9368c7..af387cf 100644 --- a/libs/sf2dlib/libsf2d/source/sf2d_texture.c +++ b/libs/sf2dlib/libsf2d/source/sf2d_texture.c @@ -78,7 +78,13 @@ sf2d_texture *sf2d_create_texture(int width, int height, sf2d_texfmt pixel_forma texture->data_size = data_size; texture->data = data; - memset(texture->data, 0, texture->data_size); + if (place == SF2D_PLACE_VRAM) { + GX_SetMemoryFill(NULL, texture->data, 0x00000000, (u32*)&((u8*)texture->data)[texture->data_size], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH, + NULL, 0x00000000, NULL, 0); + gspWaitForPSC0(); + } else { + memset(texture->data, 0, texture->data_size); + } return texture; } diff --git a/libs/sftdlib/libsftd/include/sftd.h b/libs/sftdlib/libsftd/include/sftd.h index d1a75f6..54fe73a 100644 --- a/libs/sftdlib/libsftd/include/sftd.h +++ b/libs/sftdlib/libsftd/include/sftd.h @@ -105,6 +105,8 @@ void sftd_draw_wtext(sftd_font *font, int x, int y, unsigned int color, unsigned */ void sftd_draw_wtextf(sftd_font *font, int x, int y, unsigned int color, unsigned int size, const wchar_t *text, ...); +// (ctruLua addition) Based on sftd_draw_wtext, returns the width of the text drawn. +int sftd_width_wtext(sftd_font *font, unsigned int size, const wchar_t *text); #ifdef __cplusplus } diff --git a/libs/sftdlib/libsftd/source/sftd.c b/libs/sftdlib/libsftd/source/sftd.c index dd9ea02..5b98af4 100644 --- a/libs/sftdlib/libsftd/source/sftd.c +++ b/libs/sftdlib/libsftd/source/sftd.c @@ -228,7 +228,7 @@ void sftd_draw_text(sftd_font *font, int x, int y, unsigned int color, unsigned &rect, &bitmap_left, &bitmap_top, &advance_x, &advance_y, &glyph_size); - const float draw_scale = glyph_size/(float)size; + const float draw_scale = size/(float)glyph_size; sf2d_draw_texture_part_scale_blend(font->tex_atlas->tex, pen_x + bitmap_left * draw_scale, @@ -304,7 +304,7 @@ void sftd_draw_wtext(sftd_font *font, int x, int y, unsigned int color, unsigned &rect, &bitmap_left, &bitmap_top, &advance_x, &advance_y, &glyph_size); - const float draw_scale = (float)size/glyph_size; + const float draw_scale = size/(float)glyph_size; sf2d_draw_texture_part_scale_blend(font->tex_atlas->tex, pen_x + bitmap_left * draw_scale, @@ -332,3 +332,62 @@ void sftd_draw_wtextf(sftd_font *font, int x, int y, unsigned int color, unsigne va_end(args); } +// (ctruLua addition) Based on sftd_draw_wtext, returns the width of the text drawn. +int sftd_width_wtext(sftd_font *font, unsigned int size, const wchar_t *text) +{ + FTC_FaceID face_id = (FTC_FaceID)font; + FT_Face face; + FTC_Manager_LookupFace(ftcmanager, face_id, &face); + + FT_Int charmap_index; + charmap_index = FT_Get_Charmap_Index(face->charmap); + + FT_Glyph glyph; + FT_Bool use_kerning = FT_HAS_KERNING(face); + FT_UInt glyph_index, previous = 0; + int pen_x = 0; + + FTC_ScalerRec scaler; + scaler.face_id = face_id; + scaler.width = size; + scaler.height = size; + scaler.pixel = 1; + + FT_ULong flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL; + + while (*text) { + glyph_index = FTC_CMapCache_Lookup(font->cmapcache, (FTC_FaceID)font, charmap_index, *text); + + if (use_kerning && previous && glyph_index) { + FT_Vector delta; + FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); + pen_x += delta.x >> 6; + } + + if (!texture_atlas_exists(font->tex_atlas, glyph_index)) { + FTC_ImageCache_LookupScaler(font->imagecache, &scaler, flags, glyph_index, &glyph, NULL); + + if (!atlas_add_glyph(font->tex_atlas, glyph_index, (FT_BitmapGlyph)glyph, size)) { + continue; + } + } + + bp2d_rectangle rect; + int bitmap_left, bitmap_top; + int advance_x, advance_y; + int glyph_size; + + texture_atlas_get(font->tex_atlas, glyph_index, + &rect, &bitmap_left, &bitmap_top, + &advance_x, &advance_y, &glyph_size); + + const float draw_scale = size/(float)glyph_size; + + pen_x += (advance_x >> 16) * draw_scale; + + previous = glyph_index; + text++; + } + + return pen_x; +} \ No newline at end of file diff --git a/sdcard/3ds/ctruLua/editor/VeraMono.ttf b/sdcard/3ds/ctruLua/editor/VeraMono.ttf new file mode 100644 index 0000000..139f0b4 Binary files /dev/null and b/sdcard/3ds/ctruLua/editor/VeraMono.ttf differ diff --git a/sdcard/3ds/ctruLua/editor/color.lua b/sdcard/3ds/ctruLua/editor/color.lua index c162160..e29506a 100644 --- a/sdcard/3ds/ctruLua/editor/color.lua +++ b/sdcard/3ds/ctruLua/editor/color.lua @@ -1,6 +1,16 @@ -- Colors based on the Monokai theme return { - background = 0x272822FF, - default = 0xF8F8F2FF, - cursor = 0xFF0000FF + -- General + ["background"] = 0x272822FF, + ["cursor"] = 0xF8F8F0FF, + ["default"] = 0xF8F8F2FF, + + -- Syntax + ["comment"] = 0x75715EFF, + ["string"] = 0xE6DB74FF, + ["constant.numeric"] = 0xAE81FFFF, + ["constant.language"] = 0xAE81FFFF, + ["keyword.control"] = 0xF92672FF, + ["keyword.operator"] = 0xF92672FF, + ["support.function"] = 0x66D9EFFF } \ No newline at end of file diff --git a/sdcard/3ds/ctruLua/editor/main.lua b/sdcard/3ds/ctruLua/editor/main.lua index 1bf70ed..ec14bad 100644 --- a/sdcard/3ds/ctruLua/editor/main.lua +++ b/sdcard/3ds/ctruLua/editor/main.lua @@ -5,27 +5,45 @@ local gfx = require("ctr.gfx") -- Open libs local keyboard = dofile("sdmc:/3ds/ctruLua/keyboard.lua") local openfile = dofile("sdmc:/3ds/ctruLua/openfile.lua") -local color = dofile("sdmc:/3ds/ctruLua/editor/color.lua") +local color = dofile("color.lua") +local syntax = dofile("syntax.lua") + +-- Load data +local font = gfx.font.load("VeraMono.ttf") -- Open file local path, status = openfile("Choose a file to edit", "/3ds/ctruLua/", nil, "any") if not path then return end +local lineEnding local lines = {} if status == "exist" then - for line in io.lines(path) do table.insert(lines, line) end + for line in io.lines(path, "L") do + if not lineEnding then lineEnding = line:match("([\n\r]+)$") end + table.insert(lines, line:match("^(.-)[\n\r]*$")) + end else + lineEnding = "\n" lines = { "" } end +-- Syntax coloring +local coloredLines = syntax(lines, color) + -- Variables local lineHeight = 10 local cursorX, cursorY = 1, 1 local scrollX, scrollY = 0, 0 +-- Helper functions +local function displayedText(text) + return text:gsub("\t", " ") +end + -- Set defaults gfx.set3D(false) gfx.color.setDefault(color.default) gfx.color.setBackground(color.background) +gfx.font.setDefault(font) while ctr.run() do hid.read() @@ -75,10 +93,10 @@ while ctr.run() do until t + 5 < os.time() else for i = 1, #lines, 1 do - file:write(lines[i].."\n") + file:write(lines[i]..lineEnding) gfx.startFrame(gfx.GFX_TOP) gfx.rectangle(0, 0, math.ceil(i/#lines*gfx.TOP_WIDTH), gfx.TOP_HEIGHT, 0, 0xFFFFFFFF) - gfx.color.setDefault(0x000000FF) + gfx.color.setDefault(color.background) gfx.text(gfx.TOP_WIDTH/2, gfx.TOP_HEIGHT/2, math.ceil(i/#lines*100).."%") gfx.color.setDefault(color.default) gfx.endFrame() @@ -122,6 +140,7 @@ while ctr.run() do -- Draw gfx.startFrame(gfx.GFX_TOP) + -- Lines local sI = math.floor(scrollY / lineHeight) if sI < 1 then sI = 1 end @@ -129,21 +148,30 @@ while ctr.run() do if eI > #lines then eI = #lines end for i = sI, eI, 1 do - local line = lines[i] + local x = -scrollX local y = -scrollY+ (i-1)*lineHeight - - if cursorY == i then - gfx.color.setDefault(color.cursor) - gfx.text(-scrollX, y, line:sub(1, (utf8.offset(line, cursorX) or 0)-1):gsub("\t", " ").."|", nil) -- TODO: color doesn't work + + for _,colored in ipairs(coloredLines[i]) do + local str = displayedText(colored[1]) + + gfx.color.setDefault(colored[2]) + gfx.text(x, y, str) gfx.color.setDefault(color.default) + + x = x + font:width(str) end - - gfx.text(-scrollX, y, line:gsub("\t", " "), nil) end + -- Cursor + local curline = lines[cursorY] + gfx.rectangle(-scrollX+ font:width(displayedText(curline:sub(1, (utf8.offset(curline, cursorX) or 0)-1))), + -scrollY+ (cursorY-1)*lineHeight, 1, lineHeight, 0, color.cursor) + gfx.endFrame() gfx.startFrame(gfx.GFX_BOTTOM) + + gfx.text(3, 3, "FPS: "..math.ceil(gfx.getFPS())) keyboard.draw(5, 115) @@ -151,3 +179,5 @@ while ctr.run() do gfx.render() end + +font:unload() \ No newline at end of file diff --git a/sdcard/3ds/ctruLua/editor/syntax.lua b/sdcard/3ds/ctruLua/editor/syntax.lua new file mode 100644 index 0000000..bebe3f5 --- /dev/null +++ b/sdcard/3ds/ctruLua/editor/syntax.lua @@ -0,0 +1,90 @@ +-- Each pattern should return 3 captures : start position, the string to colorize, and the end position. +local syntax = { + { "comment", { "()(%-%-.*)()$" } }, + + --["string"] = { "()(%'.*%f[%\\]%')()", "()(%\".*%f[%\\]%\")()" }, + { "string", { "()(%'[^%']*%')()", "()(%\"[^%\"]*%\")()" } }, + + { "constant.numeric", { + "%f[%d%w%.]()(0x[a-fA-F%d]+)()%f[^%d%w%.]", + "%f[%d%w%.]()([%d% ]+%.[%d% ]+)()%f[^%d%w%.]", + "%f[%d%w%.]()([%d% ]+)()%f[^%d%w%.]" + } + }, + + { "constant.language", { + "%f[%w]()(false)()%f[%W]", "%f[%w]()(nil)()%f[%W]", "%f[%w]()(true)()%f[%W]", "%f[%w]()(_G)()%f[%W]", + "%f[%w]()(_VERSION)()%f[%W]", "%f[%w]()(math.pi)()%f[%W]", "%f[%w]()(math.huge)()%f[%W]", "%f[%w]()(%.%.%.)()%f[%W]" + } + }, + + { "keyword.control", { + "%f[%w]()(break)()%f[%W]", "%f[%w]()(goto)()%f[%W]", "%f[%w]()(do)()%f[%W]", "%f[%w]()(else)()%f[%W]", + "%f[%w]()(for)()%f[%W]", "%f[%w]()(if)()%f[%W]", "%f[%w]()(elseif)()%f[%W]", "%f[%w]()(return)()%f[%W]", + "%f[%w]()(then)()%f[%W]", "%f[%w]()(repeat)()%f[%W]", "%f[%w]()(while)()%f[%W]", "%f[%w]()(until)()%f[%W]", + "%f[%w]()(end)()%f[%W]", "%f[%w]()(function)()%f[%W]", "%f[%w]()(local)()%f[%W]", "%f[%w]()(in)()%f[%W]" + } + }, + + { "keyword.operator", { + "%f[%w]()(and)()%f[%W]", "%f[%w]()(or)()%f[%W]", "%f[%w]()(not)()%f[%W]", + "()(%+)()", "()(%-)()", "()(%%)()", "()(%#)()", "()(%*)()", "()(%/%/?)()", "()(%^)()", "()(%=%=?)()", "()(%~%=?)()", + "()(%.%.)()", "()(%<%=?)()", "()(%>%=?)()", "()(%&)()", "()(%|)()", "()(%<%<)()", "()(%>%>)()", + } + }, + + { "support.function", { + "[^%.%:]()(assert)()[%( %{]", "[^%.%:]()(collectgarbage)()[%( %{]", "[^%.%:]()(dofile)()[%( %{]", + "[^%.%:]()(error)()[%( %{]", "[^%.%:]()(getfenv)()[%( %{]", "[^%.%:]()(getmetatable)()[%( %{]", + "[^%.%:]()(ipairs)()[%( %{]", "[^%.%:]()loadfile)()[%( %{]", "[^%.%:]()(loadstring)()[%( %{]", + "[^%.%:]()(module)()[%( %{]", "[^%.%:]()(next)()[%( %{]", "[^%.%:]()(pairs)()[%( %{]", + "[^%.%:]()(pcall)()[%( %{]", "[^%.%:]()(print)()[%( %{]", "[^%.%:]()(rawequal)()[%( %{]", + "[^%.%:]()(rawget)()[%( %{]", "[^%.%:]()(rawset)()[%( %{]", "[^%.%:]()(require)()[%( %{]", + "[^%.%:]()(select)()[%( %{]", "[^%.%:]()(setfenv)()[%( %{]", "[^%.%:]()(setmetatable)()[%( %{]", + "[^%.%:]()(tonumber)()[%( %{]", "[^%.%:]()(tostring)()[%( %{]", "[^%.%:]()(type)()[%( %{]", + "[^%.%:]()(unpack)()[%( %{]", "[^%.%:]()(xpcall)()[%( %{]" + } + } +} + +return function(lines, color) + local ret = {} + + for _,line in ipairs(lines) do + local colored = { { line, color.default } } + + for _, patterns in ipairs(syntax) do + local name = patterns[1] + + for _, pattern in ipairs(patterns[2]) do + local i = 1 + while i <= #colored do + local oldcolor = colored[i][2] + + if oldcolor == color.default then + local part = colored[i][1] + + local starti, match, endi = part:match(pattern) + if starti then + table.remove(colored, i) + if starti > 1 then + table.insert(colored, i, { part:sub(1, starti-1), oldcolor }) + i = i + 1 + end + table.insert(colored, i, { match, color[name] or color.default }) + if endi <= #part then + table.insert(colored, i+1, { part:sub(endi, -1), oldcolor }) + end + end + end + + i = i + 1 + end + end + end + + table.insert(ret, colored) + end + + return ret +end \ No newline at end of file diff --git a/sdcard/3ds/ctruLua/main.lua b/sdcard/3ds/ctruLua/main.lua index c4cffda..560a7f6 100644 --- a/sdcard/3ds/ctruLua/main.lua +++ b/sdcard/3ds/ctruLua/main.lua @@ -1,4 +1,10 @@ +local fs = require("ctr.fs") + repeat - local file = dofile("sdmc:/3ds/ctruLua/openfile.lua")("Choose a Lua file to execute", "/3ds/ctruLua/", ".lua", "exist") - if file then dofile(file) end + fs.setDirectory("sdmc:/3ds/ctruLua") + local file = dofile("openfile.lua")("Choose a Lua file to execute", "/3ds/ctruLua/", ".lua", "exist") + if file then + fs.setDirectory(file:match("^(.-)[^/]*$")) + dofile(file) + end until not file \ No newline at end of file diff --git a/sdcard/3ds/ctruLua/openfile.lua b/sdcard/3ds/ctruLua/openfile.lua index 82a04a4..c913944 100644 --- a/sdcard/3ds/ctruLua/openfile.lua +++ b/sdcard/3ds/ctruLua/openfile.lua @@ -29,9 +29,11 @@ return function(title, curdir, exts, type) --local was3D = gfx.get3D() TODO: implement this thing in ctruLua local wasDefault = gfx.color.getDefault() local wasBackground = gfx.color.getBackground() + local wasFont = gfx.font.getDefault() gfx.set3D(false) gfx.color.setDefault(0xFFFFFFFF) gfx.color.setBackground(0x000000FF) + gfx.font.setDefault() while ctr.run() do ctr.hid.read() @@ -130,6 +132,7 @@ return function(title, curdir, exts, type) --gfx.set3D(was3D) gfx.color.setDefault(wasDefault) gfx.color.setBackground(wasBackground) + gfx.font.setDefault(wasFont) if ret then return table.unpack(ret) diff --git a/source/font.c b/source/font.c index 8324e03..c61db9e 100644 --- a/source/font.c +++ b/source/font.c @@ -1,27 +1,126 @@ +#include +#include + #include #include "vera_ttf.h" #include #include -sftd_font *font_default; +#include "font.h" +static int font_load(lua_State *L) { + const char *path = luaL_checkstring(L, 1); + + font_userdata *font = lua_newuserdata(L, sizeof(*font)); + luaL_getmetatable(L, "LFont"); + lua_setmetatable(L, -2); + + font->font = sftd_load_font_file(path); + + // SFTD doesn't actually check if the file exist, so we have to do this ourselves. + if (font->font == NULL || access(path, F_OK) != 0) { + lua_pushnil(L); + lua_pushfstring(L, "No valid font file at %s", path); + return 2; + } + + return 1; +} + +static int font_setDefault(lua_State *L) { + if (luaL_testudata(L, 1, "LFont") == NULL) { + font_userdata *font = lua_newuserdata(L, sizeof(*font)); + luaL_getmetatable(L, "LFont"); + lua_setmetatable(L, -2); + + font->font = sftd_load_font_mem(vera_ttf, vera_ttf_size); + } + + lua_setfield(L, LUA_REGISTRYINDEX, "LFontDefault"); + + return 0; +} + +static int font_getDefault(lua_State *L) { + lua_getfield(L, LUA_REGISTRYINDEX, "LFontDefault"); + + return 1; +} + +static int font_object_width(lua_State *L) { + font_userdata *font = luaL_checkudata(L, 1, "LFont"); + if (font->font == NULL) luaL_error(L, "The font object was unloaded"); + + size_t len; + const char *text = luaL_checklstring(L, 2, &len); + + int size = luaL_optinteger(L, 3, 9); + + // Wide caracters support. (wchar = UTF32 on 3DS.) + wchar_t wtext[len]; + len = mbstowcs(wtext, text, len); + *(wtext+len) = 0x0; // text end + + lua_pushinteger(L, sftd_width_wtext(font->font, size, wtext)); + + return 1; +} + +static int font_object_unload(lua_State *L) { + font_userdata *font = luaL_checkudata(L, 1, "LFont"); + if (font->font == NULL) return 0; + + sftd_free_font(font->font); + font->font = NULL; + + return 0; +} + +// Font object methods +static const struct luaL_Reg font_object_methods[] = { + { "width", font_object_width }, + { "unload", font_object_unload }, + { "__gc", font_object_unload }, + { NULL, NULL } +}; + +// Library functions static const struct luaL_Reg font_lib[] = { + { "load", font_load }, + { "setDefault", font_setDefault }, + { "getDefault", font_getDefault }, { NULL, NULL } }; int luaopen_font_lib(lua_State *L) { + luaL_newmetatable(L, "LFont"); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, font_object_methods, 0); + luaL_newlib(L, font_lib); return 1; } void load_font_lib(lua_State *L) { - font_default = sftd_load_font_mem(vera_ttf, vera_ttf_size); // Load default font + // Load default font + font_userdata *font = lua_newuserdata(L, sizeof(*font)); + luaL_getmetatable(L, "LFont"); + lua_setmetatable(L, -2); + font->font = sftd_load_font_mem(vera_ttf, vera_ttf_size); + + lua_setfield(L, LUA_REGISTRYINDEX, "LFontDefault"); + + // Load lib luaL_requiref(L, "ctr.gfx.font", luaopen_font_lib, false); } void unload_font_lib(lua_State *L) { - sftd_free_font(font_default); // Unload current font + lua_getfield(L, LUA_REGISTRYINDEX, "LFontDefault"); + + if (luaL_testudata(L, -1, "LFont") != NULL) + sftd_free_font(((font_userdata *)lua_touserdata(L, -1))->font); // Unload current font } \ No newline at end of file diff --git a/source/font.h b/source/font.h new file mode 100644 index 0000000..888176c --- /dev/null +++ b/source/font.h @@ -0,0 +1,8 @@ +#ifndef FONT_H +#define FONT_H + +typedef struct { + sftd_font *font; +} font_userdata; + +#endif diff --git a/source/fs.c b/source/fs.c index c0b0e80..a568cb7 100644 --- a/source/fs.c +++ b/source/fs.c @@ -1,3 +1,5 @@ +#include + #include <3ds/types.h> #include <3ds/util/utf.h> #include <3ds/services/fs.h> @@ -8,7 +10,7 @@ Handle *fsuHandle; FS_archive sdmcArchive; -int fs_list(lua_State *L) { +static int fs_list(lua_State *L) { const char *path = luaL_checkstring(L, 1); lua_newtable(L); @@ -60,8 +62,40 @@ int fs_list(lua_State *L) { return 1; } +static int fs_exists(lua_State *L) { + const char *path = luaL_checkstring(L, 1); + + lua_pushboolean(L, access(path, F_OK) == 0); + + return 1; +} + +static int fs_getDirectory(lua_State *L) { + char cwd[256]; + + lua_pushstring(L, getcwd(cwd, 256)); + + return 1; +} + +static int fs_setDirectory(lua_State *L) { + const char *path = luaL_checkstring(L, 1); + + int result = chdir(path); + + if (result == 0) + lua_pushboolean(L, true); + else + lua_pushboolean(L, false); + + return 1; +} + static const struct luaL_Reg fs_lib[] = { - { "list", fs_list }, + { "list", fs_list }, + { "exists", fs_exists }, + { "getDirectory", fs_getDirectory }, + { "setDirectory", fs_setDirectory }, { NULL, NULL } }; diff --git a/source/gfx.c b/source/gfx.c index da360f8..4dc4248 100644 --- a/source/gfx.c +++ b/source/gfx.c @@ -8,6 +8,8 @@ #include #include +#include "font.h" + bool isGfxInitialised = false; void load_color_lib(lua_State *L); @@ -18,7 +20,6 @@ void load_map_lib(lua_State *L); void unload_font_lib(lua_State *L); u32 color_default; -sftd_font *font_default; static int gfx_startFrame(lua_State *L) { u8 screen = luaL_checkinteger(L, 1); @@ -124,14 +125,20 @@ static int gfx_text(lua_State *L) { int size = luaL_optinteger(L, 4, 9); u32 color = luaL_optinteger(L, 5, color_default); - // todo : font selection + font_userdata *font = luaL_testudata(L, 6, "LFont"); + if (font == NULL) { + lua_getfield(L, LUA_REGISTRYINDEX, "LFontDefault"); + font = luaL_testudata(L, -1, "LFont"); + if (font == NULL) luaL_error(L, "No default font set and no font object passed"); + } + if (font->font == NULL) luaL_error(L, "The font object was unloaded"); // Wide caracters support. (wchar = UTF32 on 3DS.) wchar_t wtext[len]; len = mbstowcs(wtext, text, len); *(wtext+len) = 0x0; // text end - sftd_draw_wtext(font_default, x, y, color, size, wtext); + sftd_draw_wtext(font->font, x, y, color, size, wtext); return 0; }