Posted 31 August 2013 - 12:20 AM
Prerequisites :
Term basics - .write, .clear, .setCursorPos, .getCursorPos (Covered in LBPHacker's tutorial)
Term basics - .getSize, .scroll, .clearLine, .setCursorBlink (Partially covered in LBPHacker's tutorial)
Familiarity with the basic Lua API
Familiarity with the String API
Hello, welcome to the AaP Renewal Project 'Term Intermediate : Rewriting BIOS write()' tutorial. As you may have guessed, in this tutorial, we are going to reimplement the BIOS write() function with our knowledge of the Term API. This tutorial is meant to show that we can use primitive functions to accomplish a more compilcated task.
First task is to write some error-checking code to ensure that the argument is really a string (or number).
All we need to do is use the type() function, which will return a string that is the type of it's argument.
If it's not a string or number, we need to call the error function, and say that we expected a string, but got something else.
If it happens to be a number, convert it into a string with tostring().
Now is where the real magic will happen. We'll iterate over the string in a for loop and print it one character at a time. Why?
Because unless we print it one character at a time, we're not going to have the fine-grained control that we need to be able to
react to things like newlines in the text or needing to wrap the line. We'll query the terminal for some position and size numbers
so that we'll react appropriately to wraps and newlines.
We need the x value to tell us where in the line, and the y value for telling us what line we're on.
We also need the height and width of the terminal.
Loop through the string one character at a time
If we encounter a line break, then react appropriately
Otherwise, it's nothing special, so we just write it
If x is more then width, then we need to wrap and scroll if we need
Nothing went wrong, so return 0
Here is the complete function :
And that's it! Now we have our own homebrew write() function. Hopefully you now see how small pieces can interact in big ways!
(Apologies for the code looking so messy, the forum is screwing it up)
Term basics - .write, .clear, .setCursorPos, .getCursorPos (Covered in LBPHacker's tutorial)
Term basics - .getSize, .scroll, .clearLine, .setCursorBlink (Partially covered in LBPHacker's tutorial)
Familiarity with the basic Lua API
Familiarity with the String API
Hello, welcome to the AaP Renewal Project 'Term Intermediate : Rewriting BIOS write()' tutorial. As you may have guessed, in this tutorial, we are going to reimplement the BIOS write() function with our knowledge of the Term API. This tutorial is meant to show that we can use primitive functions to accomplish a more compilcated task.
First task is to write some error-checking code to ensure that the argument is really a string (or number).
All we need to do is use the type() function, which will return a string that is the type of it's argument.
If it's not a string or number, we need to call the error function, and say that we expected a string, but got something else.
If it happens to be a number, convert it into a string with tostring().
function ourWrite(text)
if not (type(text) == "string" or type(text) == "number") then
error("String expected, got "..type(text))
end
if type(text) == "number" then
text = tostring(text)
end
Now is where the real magic will happen. We'll iterate over the string in a for loop and print it one character at a time. Why?
Because unless we print it one character at a time, we're not going to have the fine-grained control that we need to be able to
react to things like newlines in the text or needing to wrap the line. We'll query the terminal for some position and size numbers
so that we'll react appropriately to wraps and newlines.
We need the x value to tell us where in the line, and the y value for telling us what line we're on.
local x, y = term.getCursorPos()
We also need the height and width of the terminal.
local width, height = term.getSize()
Loop through the string one character at a time
for i = 1, #text do
If we encounter a line break, then react appropriately
if string.sub(text, i, i) == "\n" then
x = 1
-- Scroll instead of going out of bounds
if y == height then
term.scroll(1)
else
y = y + 1
end
term.setCursorPos(x, y)
Otherwise, it's nothing special, so we just write it
else
term.write(string.sub(text, i, i))
x = x + 1
If x is more then width, then we need to wrap and scroll if we need
if x > width then
x = 1
-- Same scroll check as before
if y == height then
term.scroll(1)
else
y = y + 1
end
term.setCursorPos(x, y)
end
end
end
Nothing went wrong, so return 0
return 0
end
Here is the complete function :
Spoiler
function ourWrite(text)
if not (type(text) == "string" or type(text) == "number") then
error("String expected, got "..type(text))
end
if type(text) == "number" then
text = tostring(text)
end
-- We need the x value to tell us where in the line, and the y value for telling us what line we're on.
local x, y = term.getCursorPos()
-- We also need the height and width of the terminal.
local width, height = term.getSize()
for i = 1, #text do
-- If we encounter a line break
if string.sub(text, i, i) == "\n" then
x = 1
-- Scroll instead of going out of bounds
if y == height then
term.scroll(1)
else
y = y + 1
end
term.setCursorPos(x, y)
else
-- Nothing special, so just write it
term.write(string.sub(text, i, i))
x = x + 1
-- Uh oh! We need to wrap!
if x > width then
x = 1
-- Same scroll check as before
if y == height then
term.scroll(1)
else
y = y + 1
end
term.setCursorPos(x, y)
end
end
end
-- Nothing went wrong, so return 0
return 0
end
And that's it! Now we have our own homebrew write() function. Hopefully you now see how small pieces can interact in big ways!
(Apologies for the code looking so messy, the forum is screwing it up)