A simple terminal implementation for 251 tokens (I'm pretty sure you can find some clever ways to reduce this), for your dev tools.
Currently I'm working on some editors for my game, I had to implement mouse controls, buttons and layout. However I have missed a crucial part: text input.
I have looked inside the community wiki and found out how to read the keyboard buffer. I have made this simple terminal which I'm really satisfied with, and I thought maybe it is worth to share. Nothing fancy just a shell ready to interpret whatever command you type in and hit enter.
function new_terminal(text_color, bg_color, error_color) local t = {} t.history, t.buffer, t.t_col, t.bg_col, t.err_col, t.commands, t.append, t.render = {}, "", text_color or 11, bg_color or 0, error_color or 8, { cls = function(_ENV) history = {} end }, function(_ENV, str, err) for line in all(split(tostr(str), "\n")) do add(history, { s = line, c = err and err_col or t_col }, 1) end end, function(_ENV, x, y, h) -- while there is a character in the keyboard buffer while stat(30) do -- read the next character local c = stat(31) -- backspace if c == "\b" then buffer = sub(buffer, 1, #buffer - 1) -- enter elseif c == "\r" then -- prevent pico-8's pop-up window poke(0x5f30, 1) append(_ENV, buffer) local parts = split(buffer, " ") buffer = "" local p1 = parts[1] if p1 ~= "" then if commands[p1] then local res, code = commands[p1](_ENV, parts) if (res) append(_ENV, res, code) else append(_ENV, "unknown command: " .. p1, 1) end end else buffer = buffer .. c end end rectfill(x, y, 127, y + h * 6, bg_col) -- you can remove these but then the terminal will look a bit ugly x += 1 y += 1 local lines = min(#history, h - 1) for i = lines, 1, -1 do print(history[i].s, x, y + (lines - i) * 6, history[i].c) end print(">" .. buffer .. "_", x, y + lines * 6, t_col) end return setmetatable(t, { __index = _ENV }) end -- example usage function _init() -- turn on the dev kit so we can access the keyboard poke(0x5f2d, 0x1) term = new_terminal() -- attach a command to the terminal term.commands.hello = function(_ENV, args) return "hello" .. (args[2] and " " .. args[2] or "") .. "!" end -- attach a command with multiline results term.commands.ls = function() return "a\nb\nc" end -- attach a command with possible error results term.commands.ok = function(_ENV, args) local ok = rnd() < .5 return ok and "success" or "error", not ok end end function _draw() cls(1) -- draw the terminal starting from y, y with height in rows (each row is 6 pixel tall) -- the terminal always spans to the right edge of the screen term:render(0, 22, 10) end |
[Please log in to post a comment]