From 29c55500bd3b62107600f4d675aa557eff48ef66 Mon Sep 17 00:00:00 2001 From: Alessandro Proto Date: Sun, 8 Jan 2023 00:40:33 +0100 Subject: [PATCH] Added reboot, OS improvements --- Capy64/Assets/Lua/boot/00_common.lua | 1 + Capy64/Assets/Lua/boot/01_package.lua | 1 + Capy64/Assets/Lua/boot/02_stdio.lua | 79 +++++ Capy64/Assets/Lua/boot/03_timer.lua | 8 + Capy64/Assets/Lua/boot/99_shell.lua | 13 + Capy64/Assets/Lua/init.lua | 448 +------------------------- Capy64/Assets/Lua/lib/io.lua | 283 ++++++++++++++++ Capy64/Assets/bios.lua | 4 + Capy64/BIOS/Bios.cs | 21 +- Capy64/Capy64.cs | 4 +- Capy64/IGame.cs | 1 - Capy64/LuaRuntime/Libraries/OS.cs | 31 +- Capy64/LuaRuntime/Runtime.cs | 1 + 13 files changed, 444 insertions(+), 451 deletions(-) create mode 100644 Capy64/Assets/Lua/boot/00_common.lua create mode 100644 Capy64/Assets/Lua/boot/01_package.lua create mode 100644 Capy64/Assets/Lua/boot/02_stdio.lua create mode 100644 Capy64/Assets/Lua/boot/03_timer.lua create mode 100644 Capy64/Assets/Lua/boot/99_shell.lua create mode 100644 Capy64/Assets/Lua/lib/io.lua diff --git a/Capy64/Assets/Lua/boot/00_common.lua b/Capy64/Assets/Lua/boot/00_common.lua new file mode 100644 index 0000000..eb4dd1c --- /dev/null +++ b/Capy64/Assets/Lua/boot/00_common.lua @@ -0,0 +1 @@ +os.print = print \ No newline at end of file diff --git a/Capy64/Assets/Lua/boot/01_package.lua b/Capy64/Assets/Lua/boot/01_package.lua new file mode 100644 index 0000000..54ac974 --- /dev/null +++ b/Capy64/Assets/Lua/boot/01_package.lua @@ -0,0 +1 @@ +package.path = "/lib/?.lua;/lib/?/init.lua;" .. package.path \ No newline at end of file diff --git a/Capy64/Assets/Lua/boot/02_stdio.lua b/Capy64/Assets/Lua/boot/02_stdio.lua new file mode 100644 index 0000000..3ce5655 --- /dev/null +++ b/Capy64/Assets/Lua/boot/02_stdio.lua @@ -0,0 +1,79 @@ +local term = require("term") +local expect = require("expect").expect + +function write(sText) + expect(1, sText, "string", "number") + + local w, h = term.getSize() + local x, y = term.getPos() + + local nLinesPrinted = 0 + local function newLine() + if y + 1 <= h then + term.setPos(1, y + 1) + else + term.setPos(1, h) + term.scroll(1) + end + x, y = term.getPos() + nLinesPrinted = nLinesPrinted + 1 + end + + -- Print the line with proper word wrapping + sText = tostring(sText) + while #sText > 0 do + local whitespace = string.match(sText, "^[ \t]+") + if whitespace then + -- Print whitespace + term.write(whitespace) + x, y = term.getPos() + sText = string.sub(sText, #whitespace + 1) + end + + local newline = string.match(sText, "^\n") + if newline then + -- Print newlines + newLine() + sText = string.sub(sText, 2) + end + + local text = string.match(sText, "^[^ \t\n]+") + if text then + sText = string.sub(sText, #text + 1) + if #text > w then + -- Print a multiline word + while #text > 0 do + if x > w then + newLine() + end + term.write(text) + text = string.sub(text, w - x + 2) + x, y = term.getPos() + end + else + -- Print a word normally + if x + #text - 1 > w then + newLine() + end + term.write(text) + x, y = term.getPos() + end + end + end + + return nLinesPrinted +end + +function print(...) + local nLinesPrinted = 0 + local nLimit = select("#", ...) + for n = 1, nLimit do + local s = tostring(select(n, ...)) + if n < nLimit then + s = s .. "\t" + end + nLinesPrinted = nLinesPrinted + write(s) + end + nLinesPrinted = nLinesPrinted + write("\n") + return nLinesPrinted +end \ No newline at end of file diff --git a/Capy64/Assets/Lua/boot/03_timer.lua b/Capy64/Assets/Lua/boot/03_timer.lua new file mode 100644 index 0000000..cbbb943 --- /dev/null +++ b/Capy64/Assets/Lua/boot/03_timer.lua @@ -0,0 +1,8 @@ +local timer = require("timer") + +function timer.sleep(n) + local timerId = timer.start(n) + repeat + local _, par = coroutine.yield("timer") + until par == timerId +end \ No newline at end of file diff --git a/Capy64/Assets/Lua/boot/99_shell.lua b/Capy64/Assets/Lua/boot/99_shell.lua new file mode 100644 index 0000000..9ccfc7d --- /dev/null +++ b/Capy64/Assets/Lua/boot/99_shell.lua @@ -0,0 +1,13 @@ +local term = require("term") +local colors = require("colors") + +term.setSize(51, 19) + +term.setForeground(0x59c9ff) +term.setBackground(colors.black) +term.clear() +term.setPos(1,1) + +print(os.version()) + +dofile("/bin/shell.lua") \ No newline at end of file diff --git a/Capy64/Assets/Lua/init.lua b/Capy64/Assets/Lua/init.lua index d0a6f84..560f975 100644 --- a/Capy64/Assets/Lua/init.lua +++ b/Capy64/Assets/Lua/init.lua @@ -1,446 +1,6 @@ -local term = require("term") -local timer = require("timer") -os.print = print - -package.path = "/lib/?.lua;/lib/?/init.lua;" .. package.path - -local event = require("event") -local colors = require("colors") -local expect = require("expect").expect - -function timer.sleep(n) - local timerId = timer.start(n) - repeat - local _, par = coroutine.yield("timer") - until par == timerId -end - -function write(sText) - expect(1, sText, "string", "number") - - local w, h = term.getSize() - local x, y = term.getPos() - - local nLinesPrinted = 0 - local function newLine() - if y + 1 <= h then - term.setPos(1, y + 1) - else - term.setPos(1, h) - term.scroll(1) - end - x, y = term.getPos() - nLinesPrinted = nLinesPrinted + 1 - end - - -- Print the line with proper word wrapping - sText = tostring(sText) - while #sText > 0 do - local whitespace = string.match(sText, "^[ \t]+") - if whitespace then - -- Print whitespace - term.write(whitespace) - x, y = term.getPos() - sText = string.sub(sText, #whitespace + 1) - end - - local newline = string.match(sText, "^\n") - if newline then - -- Print newlines - newLine() - sText = string.sub(sText, 2) - end - - local text = string.match(sText, "^[^ \t\n]+") - if text then - sText = string.sub(sText, #text + 1) - if #text > w then - -- Print a multiline word - while #text > 0 do - if x > w then - newLine() - end - term.write(text) - text = string.sub(text, w - x + 2) - x, y = term.getPos() - end - else - -- Print a word normally - if x + #text - 1 > w then - newLine() - end - term.write(text) - x, y = term.getPos() - end - end - end - - return nLinesPrinted -end - -function print(...) - local nLinesPrinted = 0 - local nLimit = select("#", ...) - for n = 1, nLimit do - local s = tostring(select(n, ...)) - if n < nLimit then - s = s .. "\t" - end - nLinesPrinted = nLinesPrinted + write(s) - end - nLinesPrinted = nLinesPrinted + write("\n") - return nLinesPrinted -end - -function read(_sReplaceChar, _tHistory, _fnComplete, _sDefault) - expect(1, _sReplaceChar, "string", "nil") - expect(2, _tHistory, "table", "nil") - expect(3, _fnComplete, "function", "nil") - expect(4, _sDefault, "string", "nil") - - term.setBlink(true) - - local sLine - if type(_sDefault) == "string" then - sLine = _sDefault - else - sLine = "" - end - local nHistoryPos - local nPos, nScroll = #sLine, 0 - if _sReplaceChar then - _sReplaceChar = string.sub(_sReplaceChar, 1, 1) - end - - local tCompletions - local nCompletion - local function recomplete() - if _fnComplete and nPos == #sLine then - tCompletions = _fnComplete(sLine) - if tCompletions and #tCompletions > 0 then - nCompletion = 1 - else - nCompletion = nil - end - else - tCompletions = nil - nCompletion = nil - end - end - - local function uncomplete() - tCompletions = nil - nCompletion = nil - end - - local w = term.getSize() - local sx = term.getPos() - - local function redraw(_bClear) - local cursor_pos = nPos - nScroll - if sx + cursor_pos >= w then - -- We've moved beyond the RHS, ensure we're on the edge. - nScroll = sx + nPos - w - elseif cursor_pos < 0 then - -- We've moved beyond the LHS, ensure we're on the edge. - nScroll = nPos - end - - local _, cy = term.getPos() - term.setPos(sx, cy) - local sReplace = _bClear and " " or _sReplaceChar - if sReplace then - term.write(string.rep(sReplace, math.max(#sLine - nScroll, 0))) - else - term.write(string.sub(sLine, nScroll + 1)) - end - - if nCompletion then - local sCompletion = tCompletions[nCompletion] - local oldText, oldBg - if not _bClear then - oldText = term.getForeground() - oldBg = term.getBackground() - term.setForeground(colors.white) - term.setBackground(colors.gray) - end - if sReplace then - term.write(string.rep(sReplace, #sCompletion)) - else - term.write(sCompletion) - end - if not _bClear then - term.setForeground(oldText) - term.setBackground(oldBg) - end - end - - term.setPos(sx + nPos - nScroll, cy) - end - - local function clear() - redraw(true) - end - - recomplete() - redraw() - - local function acceptCompletion() - if nCompletion then - -- Clear - clear() - - -- Find the common prefix of all the other suggestions which start with the same letter as the current one - local sCompletion = tCompletions[nCompletion] - sLine = sLine .. sCompletion - nPos = #sLine - - -- Redraw - recomplete() - redraw() - end - end - while true do - local sEvent, param, param1, param2 = event.pull() - if sEvent == "char" then - -- Typed key - clear() - sLine = string.sub(sLine, 1, nPos) .. param .. string.sub(sLine, nPos + 1) - nPos = nPos + 1 - recomplete() - redraw() - - elseif sEvent == "paste" then - -- Pasted text - clear() - sLine = string.sub(sLine, 1, nPos) .. param .. string.sub(sLine, nPos + 1) - nPos = nPos + #param - recomplete() - redraw() - - elseif sEvent == "key_down" then - if param1 == "enter" then - -- Enter/Numpad Enter - if nCompletion then - clear() - uncomplete() - redraw() - end - break - - elseif param1 == "left" then - -- Left - if nPos > 0 then - clear() - nPos = nPos - 1 - recomplete() - redraw() - end - - elseif param1 == "right" then - -- Right - if nPos < #sLine then - -- Move right - clear() - nPos = nPos + 1 - recomplete() - redraw() - else - -- Accept autocomplete - acceptCompletion() - end - - elseif param1 == "up" or param1 == "down" then - -- Up or down - if nCompletion then - -- Cycle completions - clear() - if param == "up" then - nCompletion = nCompletion - 1 - if nCompletion < 1 then - nCompletion = #tCompletions - end - elseif param == "down" then - nCompletion = nCompletion + 1 - if nCompletion > #tCompletions then - nCompletion = 1 - end - end - redraw() - - elseif _tHistory then - -- Cycle history - clear() - if param1 == "up" then - -- Up - if nHistoryPos == nil then - if #_tHistory > 0 then - nHistoryPos = #_tHistory - end - elseif nHistoryPos > 1 then - nHistoryPos = nHistoryPos - 1 - end - else - -- Down - if nHistoryPos == #_tHistory then - nHistoryPos = nil - elseif nHistoryPos ~= nil then - nHistoryPos = nHistoryPos + 1 - end - end - if nHistoryPos then - sLine = _tHistory[nHistoryPos] - nPos, nScroll = #sLine, 0 - else - sLine = "" - nPos, nScroll = 0, 0 - end - uncomplete() - redraw() - - end - - elseif param1 == "back" then - -- Backspace - if nPos > 0 then - clear() - sLine = string.sub(sLine, 1, nPos - 1) .. string.sub(sLine, nPos + 1) - nPos = nPos - 1 - if nScroll > 0 then nScroll = nScroll - 1 end - recomplete() - redraw() - end - - elseif param1 == "home" then - -- Home - if nPos > 0 then - clear() - nPos = 0 - recomplete() - redraw() - end - - elseif param1 == "delete" then - -- Delete - if nPos < #sLine then - clear() - sLine = string.sub(sLine, 1, nPos) .. string.sub(sLine, nPos + 2) - recomplete() - redraw() - end - - elseif param1 == "end" then - -- End - if nPos < #sLine then - clear() - nPos = #sLine - recomplete() - redraw() - end - - elseif param1 == "tab" then - -- Tab (accept autocomplete) - acceptCompletion() - - end - - elseif sEvent == "mouse_down" or sEvent == "mouse_drag" and param == 1 then - local _, cy = term.getPos() - if param1 >= sx and param1 <= w and param2 == cy then - -- Ensure we don't scroll beyond the current line - nPos = math.min(math.max(nScroll + param1 - sx, 0), #sLine) - redraw() - end - - elseif sEvent == "term_resize" then - -- Terminal resized - w = term.getSize() - redraw() - - end - end - - local _, cy = term.getPos() - term.setBlink(false) - term.setPos(w + 1, cy) - print() - - return sLine -end - - -function printError(...) - local r, g, b = term.getForeground() - term.setForeground(colors.red) - print(...) - term.setForeground(r, g, b) -end - -local tEnv = { - ["_echo"] = function(...) - return ... - end, - p = function(t, sv) - for k, v in pairs(t) do - if sv then - print(k, v) - else - print(k, type(v)) - end - end - end, - fs = require("fs"), -} -setmetatable(tEnv, { __index = _ENV }) - -local tCommandHistory = {} - -term.setSize(51, 19) - -term.setForeground(colors.yellow) -term.setBackground(colors.black) -term.clear() -term.setPos(1,1) -print("Lua prompt") -while true do - term.setForeground(colors.yellow) - write("> ") - term.setForeground(colors.white) - local s = read(nil, tCommandHistory) - if s:match("%S") and tCommandHistory[#tCommandHistory] ~= s then - table.insert(tCommandHistory, s) - end - - local nForcePrint = 0 - local func, e = load(s, "=lua", "t", tEnv) - local func2 = load("return _echo(" .. s .. ");", "=lua", "t", tEnv) - - if not func then - if func2 then - func = func2 - e = nil - nForcePrint = 1 - end - else - if func2 then - func = func2 - end - end - - if func then - local tResults = table.pack(pcall(func)) - if tResults[1] then - local n = 1 - while n < tResults.n or n <= nForcePrint do - local value = tResults[n + 1] - print(tostring(value)) - n = n + 1 - end - else - printError(tResults[2]) - end - else - printError(e) - end +local fs = require("fs") +local files = fs.list("/boot") +for k, v in ipairs(files) do + dofile("/boot/" .. v) end \ No newline at end of file diff --git a/Capy64/Assets/Lua/lib/io.lua b/Capy64/Assets/Lua/lib/io.lua new file mode 100644 index 0000000..b4a74d3 --- /dev/null +++ b/Capy64/Assets/Lua/lib/io.lua @@ -0,0 +1,283 @@ +local expect = require("expect").expect +local event = require("event") +local term = require("term") + +local io = {} + +function io.read(_sReplaceChar, _tHistory, _fnComplete, _sDefault) + expect(1, _sReplaceChar, "string", "nil") + expect(2, _tHistory, "table", "nil") + expect(3, _fnComplete, "function", "nil") + expect(4, _sDefault, "string", "nil") + + term.setBlink(true) + + local sLine + if type(_sDefault) == "string" then + sLine = _sDefault + else + sLine = "" + end + local nHistoryPos + local nPos, nScroll = #sLine, 0 + if _sReplaceChar then + _sReplaceChar = string.sub(_sReplaceChar, 1, 1) + end + + local tCompletions + local nCompletion + local function recomplete() + if _fnComplete and nPos == #sLine then + tCompletions = _fnComplete(sLine) + if tCompletions and #tCompletions > 0 then + nCompletion = 1 + else + nCompletion = nil + end + else + tCompletions = nil + nCompletion = nil + end + end + + local function uncomplete() + tCompletions = nil + nCompletion = nil + end + + local w = term.getSize() + local sx = term.getPos() + + local function redraw(_bClear) + local cursor_pos = nPos - nScroll + if sx + cursor_pos >= w then + -- We've moved beyond the RHS, ensure we're on the edge. + nScroll = sx + nPos - w + elseif cursor_pos < 0 then + -- We've moved beyond the LHS, ensure we're on the edge. + nScroll = nPos + end + + local _, cy = term.getPos() + term.setPos(sx, cy) + local sReplace = _bClear and " " or _sReplaceChar + if sReplace then + term.write(string.rep(sReplace, math.max(#sLine - nScroll, 0))) + else + term.write(string.sub(sLine, nScroll + 1)) + end + + if nCompletion then + local sCompletion = tCompletions[nCompletion] + local oldText, oldBg + if not _bClear then + oldText = term.getForeground() + oldBg = term.getBackground() + term.setForeground(colors.white) + term.setBackground(colors.gray) + end + if sReplace then + term.write(string.rep(sReplace, #sCompletion)) + else + term.write(sCompletion) + end + if not _bClear then + term.setForeground(oldText) + term.setBackground(oldBg) + end + end + + term.setPos(sx + nPos - nScroll, cy) + end + + local function clear() + redraw(true) + end + + recomplete() + redraw() + + local function acceptCompletion() + if nCompletion then + -- Clear + clear() + + -- Find the common prefix of all the other suggestions which start with the same letter as the current one + local sCompletion = tCompletions[nCompletion] + sLine = sLine .. sCompletion + nPos = #sLine + + -- Redraw + recomplete() + redraw() + end + end + while true do + local sEvent, param, param1, param2 = event.pull() + if sEvent == "char" then + -- Typed key + clear() + sLine = string.sub(sLine, 1, nPos) .. param .. string.sub(sLine, nPos + 1) + nPos = nPos + 1 + recomplete() + redraw() + + elseif sEvent == "paste" then + -- Pasted text + clear() + sLine = string.sub(sLine, 1, nPos) .. param .. string.sub(sLine, nPos + 1) + nPos = nPos + #param + recomplete() + redraw() + + elseif sEvent == "key_down" then + if param1 == "enter" then + -- Enter/Numpad Enter + if nCompletion then + clear() + uncomplete() + redraw() + end + break + + elseif param1 == "left" then + -- Left + if nPos > 0 then + clear() + nPos = nPos - 1 + recomplete() + redraw() + end + + elseif param1 == "right" then + -- Right + if nPos < #sLine then + -- Move right + clear() + nPos = nPos + 1 + recomplete() + redraw() + else + -- Accept autocomplete + acceptCompletion() + end + + elseif param1 == "up" or param1 == "down" then + -- Up or down + if nCompletion then + -- Cycle completions + clear() + if param == "up" then + nCompletion = nCompletion - 1 + if nCompletion < 1 then + nCompletion = #tCompletions + end + elseif param == "down" then + nCompletion = nCompletion + 1 + if nCompletion > #tCompletions then + nCompletion = 1 + end + end + redraw() + + elseif _tHistory then + -- Cycle history + clear() + if param1 == "up" then + -- Up + if nHistoryPos == nil then + if #_tHistory > 0 then + nHistoryPos = #_tHistory + end + elseif nHistoryPos > 1 then + nHistoryPos = nHistoryPos - 1 + end + else + -- Down + if nHistoryPos == #_tHistory then + nHistoryPos = nil + elseif nHistoryPos ~= nil then + nHistoryPos = nHistoryPos + 1 + end + end + if nHistoryPos then + sLine = _tHistory[nHistoryPos] + nPos, nScroll = #sLine, 0 + else + sLine = "" + nPos, nScroll = 0, 0 + end + uncomplete() + redraw() + + end + + elseif param1 == "back" then + -- Backspace + if nPos > 0 then + clear() + sLine = string.sub(sLine, 1, nPos - 1) .. string.sub(sLine, nPos + 1) + nPos = nPos - 1 + if nScroll > 0 then nScroll = nScroll - 1 end + recomplete() + redraw() + end + + elseif param1 == "home" then + -- Home + if nPos > 0 then + clear() + nPos = 0 + recomplete() + redraw() + end + + elseif param1 == "delete" then + -- Delete + if nPos < #sLine then + clear() + sLine = string.sub(sLine, 1, nPos) .. string.sub(sLine, nPos + 2) + recomplete() + redraw() + end + + elseif param1 == "end" then + -- End + if nPos < #sLine then + clear() + nPos = #sLine + recomplete() + redraw() + end + + elseif param1 == "tab" then + -- Tab (accept autocomplete) + acceptCompletion() + + end + + elseif sEvent == "mouse_down" or sEvent == "mouse_move" and param == 1 then + local _, cy = term.getPos() + if param1 >= sx and param1 <= w and param2 == cy then + -- Ensure we don't scroll beyond the current line + nPos = math.min(math.max(nScroll + param1 - sx, 0), #sLine) + redraw() + end + + elseif sEvent == "term_resize" then + -- Terminal resized + w = term.getSize() + redraw() + + end + end + + local _, cy = term.getPos() + term.setBlink(false) + term.setPos(w + 1, cy) + print() + + return sLine +end + +return io \ No newline at end of file diff --git a/Capy64/Assets/bios.lua b/Capy64/Assets/bios.lua index e2d9330..7e0b19e 100644 --- a/Capy64/Assets/bios.lua +++ b/Capy64/Assets/bios.lua @@ -5,6 +5,10 @@ local bootSleep = 2000 local bg = 0x0 local fg = 0xffffff +term.setForeground(fg) +term.setBackground(bg) +term.clear() + local function sleep(n) local timerId = timer.start(n) repeat diff --git a/Capy64/BIOS/Bios.cs b/Capy64/BIOS/Bios.cs index 00be48f..8325d43 100644 --- a/Capy64/BIOS/Bios.cs +++ b/Capy64/BIOS/Bios.cs @@ -26,7 +26,8 @@ public class Bios : IPlugin private EventEmitter _eventEmitter; private RuntimeInputEvents _runtimeInputEvents; private Drawing _drawing; - private bool CloseRuntime = false; + private static bool CloseRuntime = false; + private static bool OpenBios = false; public Bios(IGame game) { @@ -47,12 +48,18 @@ public class Bios : IPlugin if (CloseRuntime) { _runtimeInputEvents.Unregister(); - _game.LuaRuntime.Close(); - CloseRuntime = false; - StartLuaOS(); + if (OpenBios) + { + OpenBios = false; + RunBIOS(); + } + else + { + StartLuaOS(); + } } Resume(); @@ -150,6 +157,12 @@ public class Bios : IPlugin _game.Exit(); } + public static void Reboot() + { + CloseRuntime = true; + OpenBios = true; + } + private int L_OpenDataFolder(IntPtr state) { var path = FileSystem.DataPath; diff --git a/Capy64/Capy64.cs b/Capy64/Capy64.cs index 477e95c..c0d0049 100644 --- a/Capy64/Capy64.cs +++ b/Capy64/Capy64.cs @@ -20,8 +20,8 @@ namespace Capy64; public class Capy64 : Game, IGame { + public const string Version = "Capy64 a0.0.1"; public Game Game => this; - public string Version => "Capy64 a0.0.1"; public IList NativePlugins { get; private set; } public IList Plugins { get; private set; } public int Width { get; set; } = 400; @@ -102,6 +102,8 @@ public class Capy64 : Game, IGame protected override void Initialize() { + Window.Title = Version; + UpdateSize(); Window.AllowUserResizing = false; diff --git a/Capy64/IGame.cs b/Capy64/IGame.cs index 224a874..a780813 100644 --- a/Capy64/IGame.cs +++ b/Capy64/IGame.cs @@ -11,7 +11,6 @@ namespace Capy64; public interface IGame { Game Game { get; } - public string Version { get; } IList NativePlugins { get; } IList Plugins { get; } GameWindow Window { get; } diff --git a/Capy64/LuaRuntime/Libraries/OS.cs b/Capy64/LuaRuntime/Libraries/OS.cs index 9ae59ea..92e0e3b 100644 --- a/Capy64/LuaRuntime/Libraries/OS.cs +++ b/Capy64/LuaRuntime/Libraries/OS.cs @@ -20,14 +20,43 @@ public class OS : IPlugin public void LuaInit(Lua state) { state.GetGlobal("os"); + + state.PushString("version"); + state.PushCFunction(L_Version); + state.SetTable(-3); + state.PushString("shutdown"); state.PushCFunction(L_Shutdown); state.SetTable(-3); } + private static int L_Version(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.PushString(Capy64.Version); + + return 1; + } + private static int L_Shutdown(IntPtr state) { - BIOS.Bios.Shutdown(); + var L = Lua.FromIntPtr(state); + + var doReboot = false; + if (L.IsBoolean(1)) + { + doReboot = L.ToBoolean(1); + } + + if (doReboot) + { + BIOS.Bios.Reboot(); + } + else + { + BIOS.Bios.Shutdown(); + } return 0; } diff --git a/Capy64/LuaRuntime/Runtime.cs b/Capy64/LuaRuntime/Runtime.cs index 76aa801..b60932c 100644 --- a/Capy64/LuaRuntime/Runtime.cs +++ b/Capy64/LuaRuntime/Runtime.cs @@ -46,6 +46,7 @@ public class Runtime public void Init() { + Parent.SetTop(0); var initContent = File.ReadAllText(Path.Combine(FileSystem.DataPath, "init.lua")); var status = Thread.LoadString(initContent, "=init.lua"); if (status != LuaStatus.OK)