From 76589e67dd5fda2e75c6c44d5458e2b7103b5af4 Mon Sep 17 00:00:00 2001 From: IonutParau Date: Sun, 15 Feb 2026 20:27:47 +0100 Subject: [PATCH] progress but we somehow got heap corruption must fix the heap corruption --- data/OpenOS/lib/tty.lua | 1 + rewrite/luaarch.c | 43 ++++- rewrite/machine.lua | 6 + rewrite/main.c | 374 ++++++++++++++++++++++++++++++++++++---- rewrite/neonucleus.c | 183 +++++++++++++++++++- rewrite/neonucleus.h | 56 +++--- 6 files changed, 586 insertions(+), 77 deletions(-) diff --git a/data/OpenOS/lib/tty.lua b/data/OpenOS/lib/tty.lua index 455307b..ce0353d 100644 --- a/data/OpenOS/lib/tty.lua +++ b/data/OpenOS/lib/tty.lua @@ -30,6 +30,7 @@ function tty.getViewport() if window.fullscreen and screen and not screen_cache[screen] then screen_cache[screen] = true window.width, window.height = window.gpu.getViewport() + debug.print("viewport is", window.width, window.height) end return window.width, window.height, window.dx, window.dy, window.x, window.y diff --git a/rewrite/luaarch.c b/rewrite/luaarch.c index 0ab102e..7d1ae1b 100644 --- a/rewrite/luaarch.c +++ b/rewrite/luaarch.c @@ -262,6 +262,7 @@ static int luaArch_computer_popSignal(lua_State *L) { for(size_t i = 0; i < signalCount; i++) { luaArch_nnToLua(arch, i); } + nn_clearstack(c); return signalCount; fail: nn_setErrorFromExit(c, err); @@ -309,9 +310,30 @@ static int luaArch_component_invoke(lua_State *L) { return 2; } size_t retc = nn_getstacksize(arch->computer); + if(strcmp(method, "getViewport") == 0) { + printf("component.invoke(%s, %s) = %zu\n", address, method, retc); + for(size_t i = 0; i < retc; i++) { + printf("%zu. %s\n", i+1, nn_typenameof(arch->computer, i)); + } + printf("prev lua stack size: %d\n", lua_gettop(L)); + } for(size_t i = 0; i < retc; i++) { + if(strcmp(method, "getViewport") == 0) { + printf("lua stack size: %d\n", lua_gettop(L)); + } luaArch_nnToLua(arch, i); } + if(strcmp(method, "getViewport") == 0) { + printf("RECHECK STACK\n"); + for(size_t i = 0; i < retc; i++) { + printf("%zu. %s\n", i+1, nn_typenameof(arch->computer, i)); + } + printf("new lua stack size: %d\n", lua_gettop(L)); + printf("Lua rets:\n"); + for(int i = 0; i < retc; i++) { + printf("%d. %s\n", i+1, luaL_typename(L, i - retc)); + } + } nn_clearstack(arch->computer); return retc; } @@ -418,7 +440,8 @@ static int luaArch_unicode_char(lua_State *L) { if(size == 0) luaL_error(L, "codepoint #%d out of range", i); len += size; } - char *buf = malloc(len); + nn_Context *ctx = nn_getComputerContext(luaArch_from(L)->computer); + char *buf = nn_alloc(ctx, len); len = 0; for(int i = 1; i <= argc; i++) { nn_codepoint codepoint = lua_tointeger(L, i); @@ -426,7 +449,7 @@ static int luaArch_unicode_char(lua_State *L) { len += size; } lua_pushlstring(L, buf, len); - free(buf); + nn_free(ctx, buf, len); return 1; } @@ -475,15 +498,16 @@ static int luaArch_unicode_sub(lua_State *L) { return 1; } - nn_codepoint *cp = malloc(sizeof(*cp) * len); + nn_Context *ctx = nn_getComputerContext(luaArch_from(L)->computer); + nn_codepoint *cp = nn_alloc(ctx, sizeof(*cp) * len); nn_unicode_codepointsPermissive(s, slen, cp); size_t substrlen = nn_unicode_countBytes(cp + start, end - start + 1); - char *buf = malloc(substrlen); + char *buf = nn_alloc(ctx, substrlen); nn_unicode_writeBytes(buf, cp + start, end - start + 1); lua_pushlstring(L, buf, substrlen); - free(buf); - free(cp); + nn_free(ctx, buf, substrlen); + nn_free(ctx, cp, sizeof(*cp) * len); return 1; } @@ -573,6 +597,7 @@ static void luaArch_loadEnv(lua_State *L) { static nn_Exit luaArch_handler(nn_ArchitectureRequest *req) { nn_Computer *computer = req->computer; luaArch *arch = req->localState; + nn_Context *ctx = nn_getComputerContext(computer); switch(req->action) { case NN_ARCH_FREEMEM: req->freeMemory = arch->freeMem; @@ -580,10 +605,10 @@ static nn_Exit luaArch_handler(nn_ArchitectureRequest *req) { case NN_ARCH_INIT: // wrapped in a block to prevent L from leaking, because L is common in Lua code so it may be used by mistake { - arch = malloc(sizeof(*arch)); + arch = nn_alloc(ctx, sizeof(*arch)); arch->freeMem = nn_getTotalMemory(computer); arch->computer = computer; - lua_State *L = lua_newstate(luaArch_alloc, arch); + lua_State *L = luaL_newstate(); arch->L = L; req->localState = arch; luaL_openlibs(L); @@ -598,7 +623,7 @@ static nn_Exit luaArch_handler(nn_ArchitectureRequest *req) { return NN_OK; case NN_ARCH_DEINIT: lua_close(arch->L); - free(arch); + nn_free(ctx, arch, sizeof(*arch)); return NN_OK; case NN_ARCH_TICK:; lua_settop(arch->L, 1); diff --git a/rewrite/machine.lua b/rewrite/machine.lua index bf2e92d..9d6e03f 100644 --- a/rewrite/machine.lua +++ b/rewrite/machine.lua @@ -168,6 +168,12 @@ unicode.wtrunc = function(str,space) return unicode.sub(str, 1, space) end +unicode.reverse = string.reverse + +unicode.charWidth = function(s) + return 1 +end + unicode.sub = function(str, a, b) if not b then b = utf8.len(str) end if not a then a = 1 end diff --git a/rewrite/main.c b/rewrite/main.c index 48ac892..3be9390 100644 --- a/rewrite/main.c +++ b/rewrite/main.c @@ -255,6 +255,9 @@ nn_Exit ne_fsState_handler(nn_FilesystemRequest *req) { } req->size = ne_lastModified(truepath); return NN_OK; + case NN_FS_ISREADONLY: + req->size = state->isReadonly ? 1 : 0; + return NN_OK; case NN_FS_ISDIRECTORY: ne_fsState_truepath(state, truepath, req->strarg1); if(!ne_exists(truepath)) { @@ -310,7 +313,7 @@ typedef struct ne_ScreenBuffer { bool ne_ocCompatibleColors = true; void ne_remapScreen(ne_ScreenBuffer *buf) { - int depth = buf->maxDepth; + int depth = buf->depth; for(int i = 0; i < buf->maxPalette; i++) { buf->mappedPalette[i] = nn_mapDepth(buf->virtualPalette[i], depth, ne_ocCompatibleColors); @@ -322,7 +325,7 @@ void ne_remapScreen(ne_ScreenBuffer *buf) { int virtfg = pixel->fg, virtbg = pixel->bg; if(pixel->isFgPalette) virtfg = buf->mappedPalette[virtfg]; else virtfg = nn_mapDepth(virtfg, depth, ne_ocCompatibleColors); - if(pixel->isBgPalette) virtbg = buf->mappedPalette[virtfg]; + if(pixel->isBgPalette) virtbg = buf->mappedPalette[virtbg]; else virtbg = nn_mapDepth(virtbg, depth, ne_ocCompatibleColors); pixel->truefg = virtfg; @@ -331,8 +334,8 @@ void ne_remapScreen(ne_ScreenBuffer *buf) { } } -ne_ScreenBuffer *ne_newScreenBuf(nn_ScreenConfig conf, const char *keyboard) { - ne_ScreenBuffer *buf = malloc(sizeof(*buf)); +ne_ScreenBuffer *ne_newScreenBuf(nn_Context *ctx, nn_ScreenConfig conf, const char *keyboard) { + ne_ScreenBuffer *buf = nn_alloc(ctx, sizeof(*buf)); buf->maxWidth = conf.maxWidth; buf->maxHeight = conf.maxHeight; buf->width = buf->maxWidth; @@ -340,10 +343,10 @@ ne_ScreenBuffer *ne_newScreenBuf(nn_ScreenConfig conf, const char *keyboard) { buf->maxDepth = conf.maxDepth; buf->depth = buf->maxDepth; buf->maxPalette = conf.paletteColors; - buf->pixels = malloc(sizeof(ne_Pixel) * conf.maxWidth * conf.maxHeight); - buf->virtualPalette = malloc(sizeof(int) * conf.paletteColors); + buf->pixels = nn_alloc(ctx, sizeof(ne_Pixel) * conf.maxWidth * conf.maxHeight); + buf->virtualPalette = nn_alloc(ctx, sizeof(int) * conf.paletteColors); memset(buf->virtualPalette, 0, sizeof(int) * buf->maxPalette); - buf->mappedPalette = malloc(sizeof(int) * conf.paletteColors); + buf->mappedPalette = nn_alloc(ctx, sizeof(int) * conf.paletteColors); buf->keyboard = keyboard; int *palette = NULL; @@ -372,11 +375,11 @@ ne_ScreenBuffer *ne_newScreenBuf(nn_ScreenConfig conf, const char *keyboard) { return buf; } -void ne_dropScreenBuf(ne_ScreenBuffer *buf) { - free(buf->pixels); - free(buf->mappedPalette); - free(buf->virtualPalette); - free(buf); +void ne_dropScreenBuf(nn_Context *ctx, ne_ScreenBuffer *buf) { + nn_free(ctx, buf->pixels, sizeof(ne_Pixel) * buf->maxWidth * buf->maxHeight); + nn_free(ctx, buf->mappedPalette, sizeof(int) * buf->maxPalette); + nn_free(ctx, buf->virtualPalette, sizeof(int) * buf->maxPalette); + nn_free(ctx, buf, sizeof(*buf)); } ne_Pixel defaultPixel = { @@ -411,9 +414,6 @@ nn_Exit ne_screen_handler(nn_ScreenRequest *req) { ne_ScreenBuffer *buf = req->instance; switch(req->action) { case NN_SCR_DROP: - // this'd require the GPU is dropped first... - // its best we just dont bother and free later - //ne_dropScreenBuf(buf); return NN_OK; case NN_SCR_GETASPECTRATIO: req->w = 1; @@ -464,14 +464,14 @@ typedef struct ne_GPUState { int currentBg; bool isFgPalette; bool isBgPalette; - int freeMemory; + int usedMemory; int activeBuffer; int scrAddrLen; char scrAddr[NN_MAX_ADDRESS]; ne_ScreenBuffer *vramBufs[NE_MAX_VRAMBUF]; } ne_GPUState; -ne_GPUState *ne_newGPU(nn_GPU gpu) { +ne_GPUState *ne_newGPU() { ne_GPUState *state = malloc(sizeof(*state)); state->screenBuf = NULL; state->currentFg = 0xFFFFFF; @@ -479,7 +479,7 @@ ne_GPUState *ne_newGPU(nn_GPU gpu) { state->isFgPalette = false; state->isBgPalette = false; state->activeBuffer = 0; - state->freeMemory = gpu.totalVRAM; + state->usedMemory = 0; for(int i = 0; i < NE_MAX_VRAMBUF; i++) { state->vramBufs[i] = NULL; } @@ -494,6 +494,7 @@ ne_ScreenBuffer *ne_gpu_currentBuffer(ne_GPUState *state) { nn_Exit ne_gpu_handler(nn_GPURequest *req) { nn_Computer *C = req->computer; ne_GPUState *state = req->instance; + nn_Context *ctx = nn_getComputerContext(C); int maxWidth = req->gpuConf->maxWidth; int maxHeight = req->gpuConf->maxHeight; @@ -515,7 +516,7 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) { case NN_GPU_DROP: for(int i = 0; i < NE_MAX_VRAMBUF; i++) { ne_ScreenBuffer *buf = state->vramBufs[i]; - if(buf != NULL) ne_dropScreenBuf(buf); + if(buf != NULL) ne_dropScreenBuf(ctx, buf); } free(state); return NN_OK; @@ -535,14 +536,6 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) { memcpy(req->text, state->scrAddr, state->scrAddrLen); req->width = state->scrAddrLen; return NN_OK; - case NN_GPU_GETRESOLUTION: - if(state->screenBuf == NULL) { - nn_setError(C, "no screen"); - return NN_EBADCALL; - } - req->width = state->screenBuf->width; - req->height = state->screenBuf->height; - return NN_OK; case NN_GPU_GET: if(activeBuf == NULL) { nn_setError(C, "no screen"); @@ -633,7 +626,7 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) { if(w >= activeBuf->width) w = activeBuf->width - 1; if(h >= activeBuf->height) h = activeBuf->height - 1; - ne_Pixel *buf = malloc(sizeof(*buf) * w * h); + ne_Pixel *buf = nn_alloc(ctx, sizeof(*buf) * w * h); if(buf == NULL) return NN_ENOMEM; for(int oy = 0; oy < h; oy++) { @@ -648,7 +641,7 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) { ne_setPixel(activeBuf, x + ox + req->tx, y + oy + req->ty, p); } } - free(buf); + nn_free(ctx, buf, sizeof(*buf) * w * h); ne_remapScreen(activeBuf); return NN_OK; case NN_GPU_GETDEPTH: @@ -658,7 +651,11 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) { req->x = req->gpuConf->maxDepth; } return NN_OK; + case NN_GPU_MAXDEPTH: + req->x = maxDepth; + return NN_OK; case NN_GPU_GETVIEWPORT: + case NN_GPU_GETRESOLUTION: if(activeBuf == NULL) { nn_setError(C, "no screen"); return NN_EBADCALL; @@ -666,6 +663,10 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) { req->width = activeBuf->width; req->height = activeBuf->height; return NN_OK; + case NN_GPU_MAXRESOLUTION: + req->width = maxWidth; + req->height = maxHeight; + return NN_OK; case NN_GPU_GETFOREGROUND: req->x = state->currentFg; req->y = state->isFgPalette ? 1 : 0; @@ -722,10 +723,288 @@ double ne_timeProc(void *_) { return (int)(t*100) / 100.0; } +int keycode_to_oc(int keycode) { + switch (keycode) { + case KEY_NULL: + return 0; + case KEY_APOSTROPHE: + return NN_KEY_APOSTROPHE; + case KEY_COMMA: + return NN_KEY_COMMA; + case KEY_MINUS: + return NN_KEY_MINUS; + case KEY_PERIOD: + return NN_KEY_PERIOD; + case KEY_SLASH: + return NN_KEY_SLASH; + case KEY_ZERO: + return NN_KEY_0; + case KEY_ONE: + return NN_KEY_1; + case KEY_TWO: + return NN_KEY_2; + case KEY_THREE: + return NN_KEY_3; + case KEY_FOUR: + return NN_KEY_4; + case KEY_FIVE: + return NN_KEY_5; + case KEY_SIX: + return NN_KEY_6; + case KEY_SEVEN: + return NN_KEY_7; + case KEY_EIGHT: + return NN_KEY_8; + case KEY_NINE: + return NN_KEY_9; + case KEY_SEMICOLON: + return NN_KEY_SEMICOLON; + case KEY_EQUAL: + return NN_KEY_EQUALS; + case KEY_A: + return NN_KEY_A; + case KEY_B: + return NN_KEY_B; + case KEY_C: + return NN_KEY_C; + case KEY_D: + return NN_KEY_D; + case KEY_E: + return NN_KEY_E; + case KEY_F: + return NN_KEY_F; + case KEY_G: + return NN_KEY_G; + case KEY_H: + return NN_KEY_H; + case KEY_I: + return NN_KEY_I; + case KEY_J: + return NN_KEY_J; + case KEY_K: + return NN_KEY_K; + case KEY_L: + return NN_KEY_L; + case KEY_M: + return NN_KEY_M; + case KEY_N: + return NN_KEY_N; + case KEY_O: + return NN_KEY_O; + case KEY_P: + return NN_KEY_P; + case KEY_Q: + return NN_KEY_Q; + case KEY_R: + return NN_KEY_R; + case KEY_S: + return NN_KEY_S; + case KEY_T: + return NN_KEY_T; + case KEY_U: + return NN_KEY_U; + case KEY_V: + return NN_KEY_V; + case KEY_W: + return NN_KEY_W; + case KEY_X: + return NN_KEY_X; + case KEY_Y: + return NN_KEY_Y; + case KEY_Z: + return NN_KEY_Z; + case KEY_LEFT_BRACKET: + return NN_KEY_LBRACKET; + case KEY_BACKSLASH: + return NN_KEY_BACKSLASH; + case KEY_RIGHT_BRACKET: + return NN_KEY_RBRACKET; + case KEY_GRAVE: + return NN_KEY_GRAVE; + case KEY_SPACE: + return NN_KEY_SPACE; + case KEY_ESCAPE: + return 0; + case KEY_ENTER: + return NN_KEY_ENTER; + case KEY_TAB: + return NN_KEY_TAB; + case KEY_BACKSPACE: + return NN_KEY_BACK; + case KEY_INSERT: + return NN_KEY_INSERT; + case KEY_DELETE: + return NN_KEY_DELETE; + case KEY_RIGHT: + return NN_KEY_RIGHT; + case KEY_LEFT: + return NN_KEY_LEFT; + case KEY_DOWN: + return NN_KEY_DOWN; + case KEY_UP: + return NN_KEY_UP; + case KEY_PAGE_UP: + return NN_KEY_PAGEUP; + case KEY_PAGE_DOWN: + return NN_KEY_PAGEDOWN; + case KEY_HOME: + return NN_KEY_HOME; + case KEY_END: + return NN_KEY_END; + case KEY_CAPS_LOCK: + return NN_KEY_CAPITAL; + case KEY_SCROLL_LOCK: + return NN_KEY_SCROLL; + case KEY_NUM_LOCK: + return NN_KEY_NUMLOCK; + case KEY_PRINT_SCREEN: + return 0; + case KEY_PAUSE: + return NN_KEY_PAUSE; + case KEY_F1: + return NN_KEY_F1; + case KEY_F2: + return NN_KEY_F2; + case KEY_F3: + return NN_KEY_F3; + case KEY_F4: + return NN_KEY_F4; + case KEY_F5: + return NN_KEY_F5; + case KEY_F6: + return NN_KEY_F6; + case KEY_F7: + return NN_KEY_F7; + case KEY_F8: + return NN_KEY_F8; + case KEY_F9: + return NN_KEY_F9; + case KEY_F10: + return NN_KEY_F10; + case KEY_F11: + return NN_KEY_F11; + case KEY_F12: + return NN_KEY_F12; + case KEY_LEFT_SHIFT: + return NN_KEY_LSHIFT; + case KEY_LEFT_CONTROL: + return NN_KEY_LCONTROL; + case KEY_LEFT_ALT: + return NN_KEY_LMENU; + case KEY_LEFT_SUPER: + return 0; + case KEY_RIGHT_SHIFT: + return NN_KEY_RSHIFT; + case KEY_RIGHT_CONTROL: + return NN_KEY_RCONTROL; + case KEY_RIGHT_ALT: + return NN_KEY_RMENU; + case KEY_RIGHT_SUPER: + return 0; + case KEY_KB_MENU: + return 0; + case KEY_KP_0: + return NN_KEY_NUMPAD0; + case KEY_KP_1: + return NN_KEY_NUMPAD1; + case KEY_KP_2: + return NN_KEY_NUMPAD2; + case KEY_KP_3: + return NN_KEY_NUMPAD3; + case KEY_KP_4: + return NN_KEY_NUMPAD4; + case KEY_KP_5: + return NN_KEY_NUMPAD5; + case KEY_KP_6: + return NN_KEY_NUMPAD6; + case KEY_KP_7: + return NN_KEY_NUMPAD7; + case KEY_KP_8: + return NN_KEY_NUMPAD8; + case KEY_KP_9: + return NN_KEY_NUMPAD9; + case KEY_KP_DECIMAL: + return NN_KEY_NUMPADDECIMAL; + case KEY_KP_DIVIDE: + return NN_KEY_NUMPADDIV; + case KEY_KP_MULTIPLY: + return NN_KEY_NUMPADMUL; + case KEY_KP_SUBTRACT: + return NN_KEY_NUMPADSUB; + case KEY_KP_ADD: + return NN_KEY_NUMPADADD; + case KEY_KP_ENTER: + return NN_KEY_NUMPADENTER; + case KEY_KP_EQUAL: + return NN_KEY_NUMPADEQUALS; + case KEY_BACK: + return 0; + case KEY_MENU: + return 0; + case KEY_VOLUME_DOWN: + return 0; + case KEY_VOLUME_UP: + return 0; + } + return 0; +} + +size_t ne_alignAlloc(size_t num, size_t align) { + if(num % align == 0) return num; + return num + align - (num % align); +} + +typedef struct ne_memSand { + char *buf; + size_t used; + size_t cap; +} ne_memSand; + +void *ne_sandbox_alloc(void *state, void *memory, size_t oldSize, size_t newSize) { + ne_memSand *sand = (ne_memSand *)state; + + oldSize = ne_alignAlloc(oldSize, NN_ALLOC_ALIGN); + newSize = ne_alignAlloc(newSize, NN_ALLOC_ALIGN); + + // never free + if(newSize == 0) return NULL; + if(memory == NULL) { + if(sand->cap - sand->used < newSize) return NULL; + // alloc new + void *mem = sand->buf + sand->used; + sand->used += newSize; + return mem; + } + // realloc + if(newSize <= oldSize) return memory; + if(sand->cap - sand->used < newSize) return NULL; + void *mem = sand->buf + sand->used; + sand->used += newSize; + memcpy(mem, memory, oldSize); + return mem; +} + int main() { + const char *player = getenv("USER"); + if(player == NULL) player = "me"; + + bool sandboxMem = true; + nn_Context ctx; nn_initContext(&ctx); nn_initPalettes(); + + ne_memSand sand; + sand.buf = NULL; + + if(sandboxMem) { + // 1 MiB pre-allocated to prevent erasing the free-list + sand.used = NN_MiB; + sand.cap = 1 * NN_GiB; + sand.buf = malloc(sand.cap); + ctx.state = &sand; + ctx.alloc = ne_sandbox_alloc; + } ctx.time = ne_timeProc; @@ -772,14 +1051,14 @@ int main() { nn_addComponent(c, ctype, "sandbox", -1, NULL); nn_addComponent(c, etype, "eeprom", 0, etype); - ne_FsState *mainFS = ne_newFS("OpenOS", false); - nn_addComponent(c, fstype[1], "mainFS", 2, mainFS); + ne_FsState *mainFS = ne_newFS("OpenOS", true); + nn_addComponent(c, fstype[0], "mainFS", 2, mainFS); nn_addComponent(c, keytype, "mainKB", 4, NULL); - ne_ScreenBuffer *scrbuf = ne_newScreenBuf(nn_defaultScreens[1], "mainKB"); + ne_ScreenBuffer *scrbuf = ne_newScreenBuf(&ctx, nn_defaultScreens[2], "mainKB"); nn_addComponent(c, scrtype, "mainScreen", -1, scrbuf); - ne_GPUState *gpu = ne_newGPU(nn_defaultGPUs[3]); + ne_GPUState *gpu = ne_newGPU(); nn_addComponent(c, gputype, "mainGPU", 3, gpu); SetExitKey(KEY_NULL); @@ -817,12 +1096,38 @@ int main() { DrawTextCodepoint(font, p.codepoint, (Vector2) {x * pixelWidth + offX, y * pixelHeight + offY}, pixelHeight - 5, fgColor); } } + + DrawText(TextFormat("mem used: %.2f%%", (double)sand.used / sand.cap * 100), 10, 10, 20, WHITE); + EndDrawing(); + // keyboard input + + // 1: clipboard + if(IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE)) { + nn_pushClipboard(c, "mainKB", GetClipboardText(), player); + } + + while(1) { + int keycode = GetKeyPressed(); + nn_codepoint unicode = GetCharPressed(); + + if(keycode == 0 && unicode == 0) break; + + if(keycode != 0) { + if(keycode == KEY_ENTER) unicode = '\r'; + if(keycode == KEY_BACKSPACE) unicode = '\b'; + if(keycode == KEY_TAB) unicode = '\t'; + } + + nn_pushKeyDown(c, "mainKB", unicode, keycode_to_oc(keycode), player); + } + tickClock -= GetFrameTime(); if(tickClock <= 0) { tickClock = tickDelay; + nn_clearstack(c); nn_Exit e = nn_tick(c); if(e != NN_OK) { @@ -861,10 +1166,11 @@ cleanup:; nn_destroyComponentType(keytype); nn_destroyComponentType(gputype); for(size_t i = 0; i < 5; i++) nn_destroyComponentType(fstype[i]); - ne_dropScreenBuf(scrbuf); + ne_dropScreenBuf(&ctx, scrbuf); // rip the universe nn_destroyUniverse(u); UnloadFont(font); CloseWindow(); + free(sand.buf); return 0; } diff --git a/rewrite/neonucleus.c b/rewrite/neonucleus.c index 5c1cc06..7ed9217 100644 --- a/rewrite/neonucleus.c +++ b/rewrite/neonucleus.c @@ -149,9 +149,6 @@ void *nn_aralloc(nn_Arena *arena, size_t size) { size += NN_ALLOC_ALIGN - over; } - if(arena->block == NULL) { - } - nn_ArenaBlock *block = arena->block; while(block != NULL) { nn_ArenaBlock *cur = block; @@ -900,6 +897,14 @@ const char *nn_getUser(nn_Computer *computer, size_t idx) { return computer->users[idx]; } +bool nn_hasUser(nn_Computer *computer, const char *user) { + if(computer->userCount == 0) return true; + for(size_t i = 0; i < computer->userCount; i++) { + if(nn_strcmp(computer->users[i], user) == 0) return true; + } + return false; +} + void nn_setArchitecture(nn_Computer *computer, const nn_Architecture *arch) { computer->arch = *arch; } @@ -1040,6 +1045,7 @@ void nn_setErrorFromExit(nn_Computer *computer, nn_Exit exit) { nn_Exit nn_tick(nn_Computer *computer) { nn_resetCallBudget(computer); nn_resetComponentBudgets(computer); + nn_clearstack(computer); nn_Exit err; if(computer->state == NN_BOOTUP) { // init state @@ -1355,6 +1361,13 @@ nn_Exit nn_call(nn_Computer *computer, const char *address, const char *method) return err; } + if(computer->stackSize < req.returnCount) { + err = NN_EBELOWSTACK; + nn_setErrorFromExit(computer, err); + nn_clearstack(computer); + return err; + } + size_t endOfTrim = computer->stackSize - req.returnCount; for(size_t i = 0; i < endOfTrim; i++) { nn_dropValue(computer->callstack[i]); @@ -1769,8 +1782,7 @@ nn_Exit nn_pushSignal(nn_Computer *computer, size_t valueCount) { if(computer->signalCount == NN_MAX_SIGNALS) return NN_ELIMIT; if(computer->stackSize < valueCount) return NN_EBELOWSTACK; - int cost = nn_countSignalCost(computer, valueCount); - if(cost == -1) return NN_EBADSTATE; + size_t cost = nn_countSignalCost(computer, valueCount); if(cost > NN_MAX_SIGNALSIZE) return NN_ELIMIT; nn_Context ctx = computer->universe->ctx; @@ -1795,8 +1807,9 @@ nn_Exit nn_popSignal(nn_Computer *computer, size_t *valueCount) { if(valueCount != NULL) *valueCount = s.len; for(size_t i = 0; i < s.len; i++) { - nn_pushvalue(computer, s.values[i]); + computer->callstack[computer->stackSize + i] = s.values[i]; } + computer->stackSize += s.len; for(size_t i = 1; i < computer->signalCount; i++) { computer->signals[i-1] = computer->signals[i]; } @@ -2879,6 +2892,13 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) { req->returnCount = 1; return nn_pushinteger(C, greq.x); } + if(nn_strcmp(method, "maxDepth") == 0) { + greq.action = NN_GPU_MAXDEPTH; + 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); @@ -2888,11 +2908,29 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) { if(err) return err; return nn_pushinteger(C, greq.height); } + if(nn_strcmp(method, "getResolution") == 0) { + greq.action = NN_GPU_GETRESOLUTION; + 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, "maxResolution") == 0) { + greq.action = NN_GPU_MAXRESOLUTION; + 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; + if(nn_checkboolean(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; @@ -2920,7 +2958,7 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) { 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; + if(nn_checkboolean(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; @@ -2944,6 +2982,17 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) { 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"); return NN_EBADCALL; } @@ -3285,8 +3334,9 @@ bool nn_unicode_validate(const char *s, size_t len) { return true; } -size_t nn_unicode_validateFirstChar(const char *s, size_t len) { +size_t nn_unicode_validateFirstChar(const char *b, size_t len) { if(len < 1) return 0; + const unsigned char *s = (const unsigned char *)b; if(s[0] <= 0x7F) { return 1; } else if((s[0] >> 5) == 0b110) { @@ -3501,3 +3551,118 @@ nn_codepoint nn_unicode_upper(nn_codepoint codepoint) { nn_codepoint nn_unicode_lower(nn_codepoint codepoint) { return codepoint; } + +// signal helper funcs + +nn_Exit nn_pushScreenResized(nn_Computer *computer, const char *screenAddress, int newWidth, int newHeight) { + nn_Exit err = nn_pushstring(computer, "screen_resized"); + if(err) return err; + err = nn_pushstring(computer, screenAddress); + if(err) return err; + err = nn_pushinteger(computer, newWidth); + if(err) return err; + err = nn_pushinteger(computer, newHeight); + if(err) return err; + return nn_pushSignal(computer, 4); +} + +nn_Exit nn_pushTouch(nn_Computer *computer, const char *screenAddress, double x, double y, int button, const char *player) { + if(!nn_hasUser(computer, player)) return NN_OK; + nn_Exit err = nn_pushstring(computer, "touch"); + if(err) return err; + err = nn_pushstring(computer, screenAddress); + if(err) return err; + err = nn_pushnumber(computer, x); + if(err) return err; + err = nn_pushnumber(computer, y); + if(err) return err; + err = nn_pushinteger(computer, button); + if(err) return err; + err = nn_pushstring(computer, player); + if(err) return err; + return nn_pushSignal(computer, 6); +} + +nn_Exit nn_pushDrag(nn_Computer *computer, const char *screenAddress, double x, double y, int button, const char *player) { + if(!nn_hasUser(computer, player)) return NN_OK; + nn_Exit err = nn_pushstring(computer, "drag"); + if(err) return err; + err = nn_pushstring(computer, screenAddress); + if(err) return err; + err = nn_pushnumber(computer, x); + if(err) return err; + err = nn_pushnumber(computer, y); + if(err) return err; + err = nn_pushinteger(computer, button); + if(err) return err; + err = nn_pushstring(computer, player); + if(err) return err; + return nn_pushSignal(computer, 6); +} + +nn_Exit nn_pushDrop(nn_Computer *computer, const char *screenAddress, double x, double y, int button, const char *player) { + if(!nn_hasUser(computer, player)) return NN_OK; + nn_Exit err = nn_pushstring(computer, "drag"); + if(err) return err; + err = nn_pushstring(computer, screenAddress); + if(err) return err; + err = nn_pushnumber(computer, x); + if(err) return err; + err = nn_pushnumber(computer, y); + if(err) return err; + err = nn_pushinteger(computer, button); + if(err) return err; + err = nn_pushstring(computer, player); + if(err) return err; + return nn_pushSignal(computer, 6); +} + +nn_Exit nn_pushScroll(nn_Computer *computer, const char *screenAddress, double x, double y, double direction, const char *player) { + if(!nn_hasUser(computer, player)) return NN_OK; +} + +nn_Exit nn_pushWalk(nn_Computer *computer, const char *screenAddress, double x, double y, const char *player) { + if(!nn_hasUser(computer, player)) return NN_OK; +} + +nn_Exit nn_pushKeyDown(nn_Computer *computer, const char *keyboardAddress, nn_codepoint charcode, int keycode, const char *player) { + if(!nn_hasUser(computer, player)) return NN_OK; + nn_Exit err = nn_pushstring(computer, "key_down"); + if(err) return err; + err = nn_pushstring(computer, keyboardAddress); + if(err) return err; + err = nn_pushinteger(computer, charcode); + if(err) return err; + err = nn_pushinteger(computer, keycode); + if(err) return err; + return nn_pushSignal(computer, 4); +} + +nn_Exit nn_pushKeyUp(nn_Computer *computer, const char *keyboardAddress, nn_codepoint charcode, int keycode, const char *player) { + if(!nn_hasUser(computer, player)) return NN_OK; + nn_Exit err = nn_pushstring(computer, "key_down"); + if(err) return err; + err = nn_pushstring(computer, keyboardAddress); + if(err) return err; + err = nn_pushinteger(computer, charcode); + if(err) return err; + err = nn_pushinteger(computer, keycode); + if(err) return err; + return nn_pushSignal(computer, 4); +} + +nn_Exit nn_pushClipboard(nn_Computer *computer, const char *keyboardAddress, const char *clipboard, const char *player) { + if(!nn_hasUser(computer, player)) return NN_OK; + return nn_pushLClipboard(computer, keyboardAddress, clipboard, nn_strlen(clipboard), player); +} + +nn_Exit nn_pushLClipboard(nn_Computer *computer, const char *keyboardAddress, const char *clipboard, size_t len, const char *player) { + if(!nn_hasUser(computer, player)) return NN_OK; + nn_Exit err = nn_pushstring(computer, "clipboard"); + if(err) return err; + err = nn_pushstring(computer, keyboardAddress); + if(err) return err; + err = nn_pushlstring(computer, clipboard, len); + if(err) return err; + return nn_pushSignal(computer, 3); +} diff --git a/rewrite/neonucleus.h b/rewrite/neonucleus.h index 9b09806..19e3c41 100644 --- a/rewrite/neonucleus.h +++ b/rewrite/neonucleus.h @@ -221,6 +221,12 @@ typedef struct nn_Context { // call it in loops. void nn_initContext(nn_Context *ctx); +// Memory allocation!!! + +void *nn_alloc(nn_Context *ctx, size_t size); +void nn_free(nn_Context *ctx, void *memory, size_t size); +void *nn_realloc(nn_Context *ctx, void *memory, size_t oldSize, size_t newSize); + typedef enum nn_Exit { // no error NN_OK = 0, @@ -1398,32 +1404,32 @@ const char *nn_depthName(int depth); #define NN_KEY_F18 0x69 #define NN_KEY_F19 0x71 -#define NN_KEYS_KANA 0x70 -#define NN_KEYS_KANJI 0x94 -#define NN_KEYS_CONVERT 0x79 -#define NN_KEYS_NOCONVERT 0x7B -#define NN_KEYS_YEN 0x7D -#define NN_KEYS_CIRCUMFLEX 0x90 -#define NN_KEYS_AX 0x96 +#define NN_KEY_KANA 0x70 +#define NN_KEY_KANJI 0x94 +#define NN_KEY_CONVERT 0x79 +#define NN_KEY_NOCONVERT 0x7B +#define NN_KEY_YEN 0x7D +#define NN_KEY_CIRCUMFLEX 0x90 +#define NN_KEY_AX 0x96 -#define NN_KEYS_NUMPAD0 0x52 -#define NN_KEYS_NUMPAD1 0x4F -#define NN_KEYS_NUMPAD2 0x50 -#define NN_KEYS_NUMPAD3 0x51 -#define NN_KEYS_NUMPAD4 0x4B -#define NN_KEYS_NUMPAD5 0x4C -#define NN_KEYS_NUMPAD6 0x4D -#define NN_KEYS_NUMPAD7 0x47 -#define NN_KEYS_NUMPAD8 0x48 -#define NN_KEYS_NUMPAD9 0x49 -#define NN_KEYS_NUMPADMUL 0x37 -#define NN_KEYS_NUMPADDIV 0xB5 -#define NN_KEYS_NUMPADSUB 0x4A -#define NN_KEYS_NUMPADADD 0x4E -#define NN_KEYS_NUMPADDECIMAL 0x53 -#define NN_KEYS_NUMPADCOMMA 0xB3 -#define NN_KEYS_NUMPADENTER 0x9C -#define NN_KEYS_NUMPADEQUALS 0x8D +#define NN_KEY_NUMPAD0 0x52 +#define NN_KEY_NUMPAD1 0x4F +#define NN_KEY_NUMPAD2 0x50 +#define NN_KEY_NUMPAD3 0x51 +#define NN_KEY_NUMPAD4 0x4B +#define NN_KEY_NUMPAD5 0x4C +#define NN_KEY_NUMPAD6 0x4D +#define NN_KEY_NUMPAD7 0x47 +#define NN_KEY_NUMPAD8 0x48 +#define NN_KEY_NUMPAD9 0x49 +#define NN_KEY_NUMPADMUL 0x37 +#define NN_KEY_NUMPADDIV 0xB5 +#define NN_KEY_NUMPADSUB 0x4A +#define NN_KEY_NUMPADADD 0x4E +#define NN_KEY_NUMPADDECIMAL 0x53 +#define NN_KEY_NUMPADCOMMA 0xB3 +#define NN_KEY_NUMPADENTER 0x9C +#define NN_KEY_NUMPADEQUALS 0x8D // pushes a screen_resized signal nn_Exit nn_pushScreenResized(nn_Computer *computer, const char *screenAddress, int newWidth, int newHeight);