mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2026-02-15 04:03:49 +01:00
graphics
This commit is contained in:
parent
a2ddcfa030
commit
51224a46a2
@ -40,5 +40,6 @@ shell.setWorkingDirectory(os.getenv("HOME"))
|
|||||||
|
|
||||||
local home_shrc = shell.resolve(".shrc")
|
local home_shrc = shell.resolve(".shrc")
|
||||||
if fs.exists(home_shrc) then
|
if fs.exists(home_shrc) then
|
||||||
assert(loadfile(shell.resolve("source", "lua")))(home_shrc)
|
local resolved = shell.resolve("source", "lua")
|
||||||
|
assert(loadfile(resolved))(home_shrc)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -14,12 +14,10 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
debug.print("try shell")
|
|
||||||
local result, reason = xpcall(require("shell").getShell(), function(msg)
|
local result, reason = xpcall(require("shell").getShell(), function(msg)
|
||||||
return tostring(msg).."\n"..debug.traceback()
|
return tostring(msg).."\n"..debug.traceback()
|
||||||
end)
|
end)
|
||||||
if not result then
|
if not result then
|
||||||
debug.print(reason)
|
|
||||||
io.stderr:write((reason ~= nil and tostring(reason) or "unknown error") .. "\n")
|
io.stderr:write((reason ~= nil and tostring(reason) or "unknown error") .. "\n")
|
||||||
io.write("Press any key to continue.\n")
|
io.write("Press any key to continue.\n")
|
||||||
os.sleep(0.5)
|
os.sleep(0.5)
|
||||||
|
|||||||
@ -446,6 +446,12 @@ static int luaArch_unicode_sub(lua_State *L) {
|
|||||||
|
|
||||||
size_t len = nn_unicode_lenPermissive(s, slen);
|
size_t len = nn_unicode_lenPermissive(s, slen);
|
||||||
|
|
||||||
|
// OpenOS does this...
|
||||||
|
if(len == 0) {
|
||||||
|
lua_pushstring(L, "");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int start = lua_tointeger(L, 2);
|
int start = lua_tointeger(L, 2);
|
||||||
int end = lua_tointeger(L, 3);
|
int end = lua_tointeger(L, 3);
|
||||||
|
|
||||||
@ -464,6 +470,11 @@ static int luaArch_unicode_sub(lua_State *L) {
|
|||||||
if(end < 0) end = 0;
|
if(end < 0) end = 0;
|
||||||
if(end >= len) end = len-1;
|
if(end >= len) end = len-1;
|
||||||
|
|
||||||
|
if(start > end) {
|
||||||
|
lua_pushstring(L, "");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
nn_codepoint *cp = malloc(sizeof(*cp) * len);
|
nn_codepoint *cp = malloc(sizeof(*cp) * len);
|
||||||
nn_unicode_codepointsPermissive(s, slen, cp);
|
nn_unicode_codepointsPermissive(s, slen, cp);
|
||||||
|
|
||||||
@ -484,6 +495,11 @@ static int luaArch_unicode_wlen(lua_State *L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int luaArch_unicode_wtrunc(lua_State *L) {
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void luaArch_loadEnv(lua_State *L) {
|
static void luaArch_loadEnv(lua_State *L) {
|
||||||
lua_createtable(L, 0, 10);
|
lua_createtable(L, 0, 10);
|
||||||
int computer = lua_gettop(L);
|
int computer = lua_gettop(L);
|
||||||
@ -547,8 +563,10 @@ static void luaArch_loadEnv(lua_State *L) {
|
|||||||
lua_setfield(L, component, "len");
|
lua_setfield(L, component, "len");
|
||||||
lua_pushcfunction(L, luaArch_unicode_sub);
|
lua_pushcfunction(L, luaArch_unicode_sub);
|
||||||
lua_setfield(L, component, "sub");
|
lua_setfield(L, component, "sub");
|
||||||
lua_pushcfunction(L, luaArch_unicode_wlen);
|
lua_pushcfunction(L, luaArch_unicode_len);
|
||||||
lua_setfield(L, component, "wlen");
|
lua_setfield(L, component, "wlen");
|
||||||
|
lua_pushcfunction(L, luaArch_unicode_wtrunc);
|
||||||
|
lua_setfield(L, component, "wtrunc");
|
||||||
lua_setglobal(L, "unicode");
|
lua_setglobal(L, "unicode");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,9 @@ function coroutine.resume(co, ...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local clist, cinvoke, computer, component, print = component.list, component.invoke, computer, component, print
|
local clist, cinvoke, computer, component, print, unicode = component.list, component.invoke, computer, component, print, unicode
|
||||||
debug.print = print
|
debug.print = print
|
||||||
|
debug.sysyield = sysyield
|
||||||
|
|
||||||
function component.list(ctype, exact)
|
function component.list(ctype, exact)
|
||||||
local list = clist()
|
local list = clist()
|
||||||
@ -155,6 +156,44 @@ function computer.pullSignal(timeout)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unicode.upper, unicode.lower = string.upper, string.lower
|
||||||
|
|
||||||
|
unicode.isWide = function(s)
|
||||||
|
local c = unicode.sub(s, 1, 1)
|
||||||
|
return unicode.wlen(c) > unicode.len(c)
|
||||||
|
end
|
||||||
|
|
||||||
|
unicode.wtrunc = function(str,space)
|
||||||
|
space = space - 1
|
||||||
|
return unicode.sub(str, 1, space)
|
||||||
|
end
|
||||||
|
|
||||||
|
unicode.sub = function(str, a, b)
|
||||||
|
if not b then b = utf8.len(str) end
|
||||||
|
if not a then a = 1 end
|
||||||
|
-- a = math.max(a,1)
|
||||||
|
|
||||||
|
if a < 0 then
|
||||||
|
-- negative
|
||||||
|
|
||||||
|
a = utf8.len(str) + a + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if b < 0 then
|
||||||
|
b = utf8.len(str) + b + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if a > b then return "" end
|
||||||
|
|
||||||
|
if b >= utf8.len(str) then b = #str else b = utf8.offset(str,b+1)-1 end
|
||||||
|
|
||||||
|
if a > utf8.len(str) then return "" end
|
||||||
|
a = utf8.offset(str,a)
|
||||||
|
|
||||||
|
return str:sub(a,b)
|
||||||
|
-- return str:sub(a, b)
|
||||||
|
end
|
||||||
|
|
||||||
function checkArg(arg, val, ...)
|
function checkArg(arg, val, ...)
|
||||||
local t = {...}
|
local t = {...}
|
||||||
for i=1,#t do
|
for i=1,#t do
|
||||||
@ -165,7 +204,7 @@ end
|
|||||||
|
|
||||||
if os.getenv("NN_REPL") == "1" then
|
if os.getenv("NN_REPL") == "1" then
|
||||||
while true do
|
while true do
|
||||||
io.write("lua> ")
|
io.write("\x1b[34mlua>\x1b[0m ")
|
||||||
io.flush()
|
io.flush()
|
||||||
local l = io.read("l")
|
local l = io.read("l")
|
||||||
if not l then break end
|
if not l then break end
|
||||||
@ -176,6 +215,7 @@ if os.getenv("NN_REPL") == "1" then
|
|||||||
f, err = load(l, "=repl")
|
f, err = load(l, "=repl")
|
||||||
if f then f() else print(err) end
|
if f then f() else print(err) end
|
||||||
end
|
end
|
||||||
|
coroutine.yield()
|
||||||
end
|
end
|
||||||
io.write("\n")
|
io.write("\n")
|
||||||
print("exiting repl")
|
print("exiting repl")
|
||||||
|
|||||||
112
rewrite/main.c
112
rewrite/main.c
@ -153,12 +153,16 @@ nn_Exit ne_fsState_handler(nn_FilesystemRequest *req) {
|
|||||||
switch(mode[0]) {
|
switch(mode[0]) {
|
||||||
case 'r':
|
case 'r':
|
||||||
mode = "rb";
|
mode = "rb";
|
||||||
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
mode = "wb";
|
mode = "wb";
|
||||||
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
mode = "ab";
|
mode = "ab";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
mode = "rb";
|
mode = "rb";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ne_fsState_truepath(state, truepath, path);
|
ne_fsState_truepath(state, truepath, path);
|
||||||
|
|
||||||
@ -568,15 +572,21 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) {
|
|||||||
|
|
||||||
x = req->x;
|
x = req->x;
|
||||||
y = req->y;
|
y = req->y;
|
||||||
for(int i = 0; i < req->width; i++) {
|
const char *s = req->text;
|
||||||
|
for(int i = 0; i < req->width;) {
|
||||||
if(!ne_inScreenBuf(activeBuf, x, y)) break;
|
if(!ne_inScreenBuf(activeBuf, x, y)) break;
|
||||||
|
size_t w = nn_unicode_validateFirstChar(s + i, req->width - i);
|
||||||
ne_Pixel p = {
|
ne_Pixel p = {
|
||||||
.fg = state->currentFg,
|
.fg = state->currentFg,
|
||||||
.bg = state->currentBg,
|
.bg = state->currentBg,
|
||||||
.isFgPalette = state->isFgPalette,
|
.isFgPalette = state->isFgPalette,
|
||||||
.isBgPalette = state->isBgPalette,
|
.isBgPalette = state->isBgPalette,
|
||||||
.codepoint = req->text[i],
|
.codepoint = (unsigned char)s[i],
|
||||||
};
|
};
|
||||||
|
if(w > 0) {
|
||||||
|
p.codepoint = nn_unicode_firstCodepoint(s + i);
|
||||||
|
i += w;
|
||||||
|
} else i++;
|
||||||
ne_setPixel(activeBuf, x, y, p);
|
ne_setPixel(activeBuf, x, y, p);
|
||||||
x += dx;
|
x += dx;
|
||||||
y += dy;
|
y += dy;
|
||||||
@ -592,8 +602,7 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) {
|
|||||||
y = req->y;
|
y = req->y;
|
||||||
w = req->width;
|
w = req->width;
|
||||||
h = req->height;
|
h = req->height;
|
||||||
if(x < 1) x = 1;
|
// prevent CPU DoS
|
||||||
if(y < 1) y = 1;
|
|
||||||
if(w >= activeBuf->width) w = activeBuf->width - 1;
|
if(w >= activeBuf->width) w = activeBuf->width - 1;
|
||||||
if(h >= activeBuf->height) h = activeBuf->height - 1;
|
if(h >= activeBuf->height) h = activeBuf->height - 1;
|
||||||
|
|
||||||
@ -609,6 +618,93 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) {
|
|||||||
ne_setPixel(activeBuf, x + ox, y + oy, p);
|
ne_setPixel(activeBuf, x + ox, y + oy, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ne_remapScreen(activeBuf);
|
||||||
|
return NN_OK;
|
||||||
|
case NN_GPU_COPY:
|
||||||
|
if(activeBuf == NULL) {
|
||||||
|
nn_setError(C, "no screen");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
x = req->x;
|
||||||
|
y = req->y;
|
||||||
|
w = req->width;
|
||||||
|
h = req->height;
|
||||||
|
// prevent CPU DoS
|
||||||
|
if(w >= activeBuf->width) w = activeBuf->width - 1;
|
||||||
|
if(h >= activeBuf->height) h = activeBuf->height - 1;
|
||||||
|
|
||||||
|
ne_Pixel *buf = malloc(sizeof(*buf) * w * h);
|
||||||
|
if(buf == NULL) return NN_ENOMEM;
|
||||||
|
|
||||||
|
for(int oy = 0; oy < h; oy++) {
|
||||||
|
for(int ox = 0; ox < w; ox++) {
|
||||||
|
buf[oy * w + ox] = ne_getPixel(activeBuf, x + ox, y + oy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int oy = 0; oy < h; oy++) {
|
||||||
|
for(int ox = 0; ox < w; ox++) {
|
||||||
|
p = buf[oy * w + ox];
|
||||||
|
ne_setPixel(activeBuf, x + ox + req->tx, y + oy + req->ty, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
ne_remapScreen(activeBuf);
|
||||||
|
return NN_OK;
|
||||||
|
case NN_GPU_GETDEPTH:
|
||||||
|
if(activeBuf != NULL) {
|
||||||
|
req->x = activeBuf->depth;
|
||||||
|
} else {
|
||||||
|
req->x = req->gpuConf->maxDepth;
|
||||||
|
}
|
||||||
|
return NN_OK;
|
||||||
|
case NN_GPU_GETVIEWPORT:
|
||||||
|
if(activeBuf == NULL) {
|
||||||
|
nn_setError(C, "no screen");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
req->width = activeBuf->width;
|
||||||
|
req->height = activeBuf->height;
|
||||||
|
return NN_OK;
|
||||||
|
case NN_GPU_GETFOREGROUND:
|
||||||
|
req->x = state->currentFg;
|
||||||
|
req->y = state->isFgPalette ? 1 : 0;
|
||||||
|
return NN_OK;
|
||||||
|
case NN_GPU_GETBACKGROUND:
|
||||||
|
req->x = state->currentBg;
|
||||||
|
req->y = state->isBgPalette ? 1 : 0;
|
||||||
|
return NN_OK;
|
||||||
|
case NN_GPU_SETFOREGROUND:
|
||||||
|
x = req->x;
|
||||||
|
y = req->y;
|
||||||
|
if(y != 0) {
|
||||||
|
// validate the palette index
|
||||||
|
if(activeBuf == NULL || x < 0 || x >= activeBuf->maxPalette) {
|
||||||
|
nn_setError(C, "invalid palette index");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req->x = state->currentFg;
|
||||||
|
req->y = state->isFgPalette ? 1 : 0;
|
||||||
|
state->currentFg = x;
|
||||||
|
state->isFgPalette = y != 0;
|
||||||
|
ne_remapScreen(activeBuf);
|
||||||
|
return NN_OK;
|
||||||
|
case NN_GPU_SETBACKGROUND:
|
||||||
|
x = req->x;
|
||||||
|
y = req->y;
|
||||||
|
if(y != 0) {
|
||||||
|
// validate the palette index
|
||||||
|
if(activeBuf == NULL || x < 0 || x >= activeBuf->maxPalette) {
|
||||||
|
nn_setError(C, "invalid palette index");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req->x = state->currentBg;
|
||||||
|
req->y = state->isBgPalette ? 1 : 0;
|
||||||
|
state->currentBg = x;
|
||||||
|
state->isBgPalette = y != 0;
|
||||||
|
ne_remapScreen(activeBuf);
|
||||||
return NN_OK;
|
return NN_OK;
|
||||||
}
|
}
|
||||||
return NN_OK;
|
return NN_OK;
|
||||||
@ -620,11 +716,19 @@ Color ne_processColor(unsigned int color) {
|
|||||||
return GetColor(color);
|
return GetColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double ne_timeProc(void *_) {
|
||||||
|
(void)_;
|
||||||
|
double t = GetTime();
|
||||||
|
return (int)(t*100) / 100.0;
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
nn_Context ctx;
|
nn_Context ctx;
|
||||||
nn_initContext(&ctx);
|
nn_initContext(&ctx);
|
||||||
nn_initPalettes();
|
nn_initPalettes();
|
||||||
|
|
||||||
|
ctx.time = ne_timeProc;
|
||||||
|
|
||||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||||
InitWindow(800, 600, "NeoNucleus Test Emulator");
|
InitWindow(800, 600, "NeoNucleus Test Emulator");
|
||||||
|
|
||||||
|
|||||||
@ -2752,11 +2752,15 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) {
|
|||||||
greq.text = (char *)nn_tolstring(C, 0, &len);
|
greq.text = (char *)nn_tolstring(C, 0, &len);
|
||||||
greq.width = len;
|
greq.width = len;
|
||||||
greq.x = nn_toboolean(C, 1) ? 1 : 0;
|
greq.x = nn_toboolean(C, 1) ? 1 : 0;
|
||||||
return state->handler(&greq);
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
return nn_pushbool(C, true);
|
||||||
}
|
}
|
||||||
if(nn_strcmp(method, "unbind") == 0) {
|
if(nn_strcmp(method, "unbind") == 0) {
|
||||||
greq.action = NN_GPU_UNBIND;
|
greq.action = NN_GPU_UNBIND;
|
||||||
return state->handler(&greq);
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
return nn_pushbool(C, true);
|
||||||
}
|
}
|
||||||
if(nn_strcmp(method, "getScreen") == 0) {
|
if(nn_strcmp(method, "getScreen") == 0) {
|
||||||
char buf[NN_MAX_ADDRESS];
|
char buf[NN_MAX_ADDRESS];
|
||||||
@ -2798,6 +2802,148 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) {
|
|||||||
req->returnCount = 1;
|
req->returnCount = 1;
|
||||||
return nn_pushbool(C, true);
|
return nn_pushbool(C, true);
|
||||||
}
|
}
|
||||||
|
if(nn_strcmp(method, "get") == 0) {
|
||||||
|
nn_costComponent(C, req->compAddress, conf.setPerTick);
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 1, "bad argument #2 (integer expected)")) return NN_EBADCALL;
|
||||||
|
greq.action = NN_GPU_GET;
|
||||||
|
greq.x = nn_tointeger(C, 0);
|
||||||
|
greq.y = nn_tointeger(C, 1);
|
||||||
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
req->returnCount = 5;
|
||||||
|
char buf[NN_MAX_UNICODE_BUFFER];
|
||||||
|
size_t len = nn_unicode_codepointToChar(buf, greq.codepoint);
|
||||||
|
err = nn_pushlstring(C, buf, len);
|
||||||
|
if(err) return err;
|
||||||
|
err = nn_pushinteger(C, greq.width);
|
||||||
|
if(err) return err;
|
||||||
|
err = nn_pushinteger(C, greq.height);
|
||||||
|
if(err) return err;
|
||||||
|
if(greq.dest == -1) err = nn_pushnull(C);
|
||||||
|
else err = nn_pushinteger(C, greq.dest);
|
||||||
|
if(err) return err;
|
||||||
|
if(greq.src == -1) err = nn_pushnull(C);
|
||||||
|
else err = nn_pushinteger(C, greq.src);
|
||||||
|
if(err) return err;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(nn_strcmp(method, "fill") == 0) {
|
||||||
|
nn_costComponent(C, req->compAddress, conf.fillPerTick);
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 1, "bad argument #2 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 2, "bad argument #3 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 3, "bad argument #4 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkstring(C, 4, "bad argument #5 (string expected)")) return NN_EBADCALL;
|
||||||
|
greq.action = NN_GPU_FILL;
|
||||||
|
size_t len;
|
||||||
|
const char *text = nn_tolstring(C, 4, &len);
|
||||||
|
if(nn_unicode_validateFirstChar(text, len) == 0) {
|
||||||
|
nn_setError(C, "invalid UTF-8 character");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
greq.codepoint = nn_unicode_firstCodepoint(text);
|
||||||
|
greq.x = nn_tointeger(C, 0);
|
||||||
|
greq.y = nn_tointeger(C, 1);
|
||||||
|
greq.width = nn_tointeger(C, 2);
|
||||||
|
greq.height = nn_tointeger(C, 3);
|
||||||
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushbool(C, true);
|
||||||
|
}
|
||||||
|
if(nn_strcmp(method, "copy") == 0) {
|
||||||
|
nn_costComponent(C, req->compAddress, conf.copyPerTick);
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 1, "bad argument #2 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 2, "bad argument #3 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 3, "bad argument #4 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 4, "bad argument #5 (integer expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 5, "bad argument #6 (integer expected)")) return NN_EBADCALL;
|
||||||
|
greq.action = NN_GPU_COPY;
|
||||||
|
greq.x = nn_tointeger(C, 0);
|
||||||
|
greq.y = nn_tointeger(C, 1);
|
||||||
|
greq.width = nn_tointeger(C, 2);
|
||||||
|
greq.height = nn_tointeger(C, 3);
|
||||||
|
greq.tx = nn_tointeger(C, 4);
|
||||||
|
greq.ty = nn_tointeger(C, 5);
|
||||||
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushbool(C, true);
|
||||||
|
}
|
||||||
|
if(nn_strcmp(method, "getDepth") == 0) {
|
||||||
|
greq.action = NN_GPU_GETDEPTH;
|
||||||
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushinteger(C, greq.x);
|
||||||
|
}
|
||||||
|
if(nn_strcmp(method, "getViewport") == 0) {
|
||||||
|
greq.action = NN_GPU_GETVIEWPORT;
|
||||||
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
req->returnCount = 2;
|
||||||
|
err = nn_pushinteger(C, greq.width);
|
||||||
|
if(err) return err;
|
||||||
|
return nn_pushinteger(C, greq.height);
|
||||||
|
}
|
||||||
|
if(nn_strcmp(method, "setForeground") == 0) {
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
err = nn_defaultboolean(C, 1, false);
|
||||||
|
if(err) return err;
|
||||||
|
if(nn_checkinteger(C, 1, "bad argument #2 (boolean expected)")) return NN_EBADCALL;
|
||||||
|
greq.action = NN_GPU_SETFOREGROUND;
|
||||||
|
greq.x = nn_tointeger(C, 0);
|
||||||
|
greq.y = nn_toboolean(C, 1) ? 1 : 0;
|
||||||
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
req->returnCount = 2;
|
||||||
|
err = nn_pushinteger(C, greq.x);
|
||||||
|
if(err) return err;
|
||||||
|
err = nn_pushbool(C, greq.y != 0);
|
||||||
|
if(err) return err;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(nn_strcmp(method, "getForeground") == 0) {
|
||||||
|
greq.action = NN_GPU_GETFOREGROUND;
|
||||||
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
req->returnCount = 2;
|
||||||
|
err = nn_pushinteger(C, greq.x);
|
||||||
|
if(err) return err;
|
||||||
|
err = nn_pushbool(C, greq.y != 0);
|
||||||
|
if(err) return err;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(nn_strcmp(method, "setBackground") == 0) {
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
err = nn_defaultboolean(C, 1, false);
|
||||||
|
if(err) return err;
|
||||||
|
if(nn_checkinteger(C, 1, "bad argument #2 (boolean expected)")) return NN_EBADCALL;
|
||||||
|
greq.action = NN_GPU_SETBACKGROUND;
|
||||||
|
greq.x = nn_tointeger(C, 0);
|
||||||
|
greq.y = nn_toboolean(C, 1) ? 1 : 0;
|
||||||
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
req->returnCount = 2;
|
||||||
|
err = nn_pushinteger(C, greq.x);
|
||||||
|
if(err) return err;
|
||||||
|
err = nn_pushbool(C, greq.y != 0);
|
||||||
|
if(err) return err;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(nn_strcmp(method, "getBackground") == 0) {
|
||||||
|
greq.action = NN_GPU_GETBACKGROUND;
|
||||||
|
err = state->handler(&greq);
|
||||||
|
if(err) return err;
|
||||||
|
req->returnCount = 2;
|
||||||
|
err = nn_pushinteger(C, greq.x);
|
||||||
|
if(err) return err;
|
||||||
|
err = nn_pushbool(C, greq.y != 0);
|
||||||
|
if(err) return err;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
nn_setError(C, "method not yet implemented");
|
nn_setError(C, "method not yet implemented");
|
||||||
return NN_EBADCALL;
|
return NN_EBADCALL;
|
||||||
}
|
}
|
||||||
@ -3254,7 +3400,7 @@ size_t nn_unicode_codepointSize(nn_codepoint codepoint) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nn_unicode_codepointToChar(char buffer[NN_MAXIMUM_UNICODE_BUFFER], nn_codepoint codepoint) {
|
size_t nn_unicode_codepointToChar(char buffer[NN_MAX_UNICODE_BUFFER], nn_codepoint codepoint) {
|
||||||
size_t codepointSize = nn_unicode_codepointSize(codepoint);
|
size_t codepointSize = nn_unicode_codepointSize(codepoint);
|
||||||
|
|
||||||
if (codepointSize == 1) {
|
if (codepointSize == 1) {
|
||||||
@ -3304,7 +3450,9 @@ size_t nn_unicode_wlen(const char *s, size_t len) {
|
|||||||
for(size_t i = 0; i < len;) {
|
for(size_t i = 0; i < len;) {
|
||||||
nn_codepoint codepoint = nn_unicode_firstCodepoint(s + i);
|
nn_codepoint codepoint = nn_unicode_firstCodepoint(s + i);
|
||||||
size_t size = nn_unicode_codepointSize(codepoint);
|
size_t size = nn_unicode_codepointSize(codepoint);
|
||||||
wlen += nn_unicode_charWidth(codepoint);
|
size_t width = nn_unicode_charWidth(codepoint);
|
||||||
|
if(width == 0) width = 1;
|
||||||
|
wlen += width;
|
||||||
i += size;
|
i += size;
|
||||||
}
|
}
|
||||||
return wlen;
|
return wlen;
|
||||||
@ -3315,12 +3463,14 @@ size_t nn_unicode_wlenPermissive(const char *s, size_t len) {
|
|||||||
for(size_t i = 0; i < len;) {
|
for(size_t i = 0; i < len;) {
|
||||||
if(nn_unicode_validateFirstChar(s + i, len - i) == 0) {
|
if(nn_unicode_validateFirstChar(s + i, len - i) == 0) {
|
||||||
size_t width = nn_unicode_charWidth((unsigned char)s[i]);
|
size_t width = nn_unicode_charWidth((unsigned char)s[i]);
|
||||||
|
if(width == 0) width = 1;
|
||||||
wlen += width;
|
wlen += width;
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
nn_codepoint codepoint = nn_unicode_firstCodepoint(s + i);
|
nn_codepoint codepoint = nn_unicode_firstCodepoint(s + i);
|
||||||
size_t size = nn_unicode_codepointSize(codepoint);
|
size_t size = nn_unicode_codepointSize(codepoint);
|
||||||
size_t width = nn_unicode_charWidth(codepoint);
|
size_t width = nn_unicode_charWidth(codepoint);
|
||||||
|
if(width == 0) width = 1;
|
||||||
wlen += width;
|
wlen += width;
|
||||||
i += size;
|
i += size;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,7 +85,7 @@ extern "C" {
|
|||||||
#define NN_MAX_USERNAME 128
|
#define NN_MAX_USERNAME 128
|
||||||
|
|
||||||
// the maximum size of a UTF-8 character
|
// the maximum size of a UTF-8 character
|
||||||
#define NN_MAXIMUM_UNICODE_BUFFER 4
|
#define NN_MAX_UNICODE_BUFFER 4
|
||||||
|
|
||||||
// the maximum size of a component error message. If the error is bigger than this,
|
// the maximum size of a component error message. If the error is bigger than this,
|
||||||
// it is truncated.
|
// it is truncated.
|
||||||
@ -126,7 +126,7 @@ nn_codepoint nn_unicode_firstCodepoint(const char *s);
|
|||||||
size_t nn_unicode_codepointSize(nn_codepoint codepoint);
|
size_t nn_unicode_codepointSize(nn_codepoint codepoint);
|
||||||
// Writes the UTF-8 bytes for a given codepoint into buffer.
|
// Writes the UTF-8 bytes for a given codepoint into buffer.
|
||||||
// It does NOT write a NULL terminator, but it does return the length.
|
// It does NOT write a NULL terminator, but it does return the length.
|
||||||
size_t nn_unicode_codepointToChar(char buffer[NN_MAXIMUM_UNICODE_BUFFER], nn_codepoint codepoint);
|
size_t nn_unicode_codepointToChar(char buffer[NN_MAX_UNICODE_BUFFER], nn_codepoint codepoint);
|
||||||
// the width, on a screen, for a codepoint.
|
// the width, on a screen, for a codepoint.
|
||||||
// This matters for emojies.
|
// This matters for emojies.
|
||||||
size_t nn_unicode_charWidth(nn_codepoint codepoint);
|
size_t nn_unicode_charWidth(nn_codepoint codepoint);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user