Skip to content

Instantly share code, notes, and snippets.

@NEO97online
Created January 25, 2021 05:34
Show Gist options
  • Save NEO97online/a8d3dd8aa2f591adf52fa9963b7429ea to your computer and use it in GitHub Desktop.
Save NEO97online/a8d3dd8aa2f591adf52fa9963b7429ea to your computer and use it in GitHub Desktop.
GDScript Terminal
class_name Terminal
extends Control
export var font: DynamicFont
const BLACK = "§0"
const WHITE = "§1"
const RED = "§2"
const ORANGE = "§3"
const YELLOW = "§4"
const GREEN = "§5"
const BLUE = "§6"
const INDIGO = "§7"
const VIOLET = "§8"
const GRAY = "§9"
const palette = {
"§0": Color.black,
"§1": Color.whitesmoke,
"§2": Color.red,
"§3": Color.orange,
"§4": Color.yellow,
"§5": Color.green,
"§6": Color.blue,
"§7": Color.indigo,
"§8": Color.purple,
"§9": Color.gray,
}
var fs := FileSystem.new()
var history := []
var input := ""
var ps1 = YELLOW + "~ " + WHITE + "> "
var tab_width := 4
var window_height := 0
var line_height := 20
var char_width := 10
var scroll_y := 0
var cursor_pos := Vector2.ZERO
var cursor_size := Vector2(char_width, line_height)
var show_cursor := true
var tick := 0
var label
func strip_codes(text: String) -> String:
var output := ""
var i := 0
while i < text.length():
if text[i] == "§":
i += 2
else:
output += text[i]
i += 1
return output
func get_max_lines() -> int:
return int(window_height / line_height) - 1
func reset_cursor():
cursor_pos.x = strip_codes(ps1).length() * char_width
func draw_text_line(text: String, y: int):
var color = Color.whitesmoke
var i := 0
var x := 0
while i < text.length():
if text[i] == "§":
var color_code = text[i] + text[i+1]
color = palette[color_code]
i += 2
elif text[i] == " ":
x += char_width * tab_width
i += 1
else:
draw_string(font, Vector2(x, y), text[i], color)
x += char_width
i += 1
func add_text(text: String):
history.push_back(text)
if history.size() > get_max_lines():
scroll_y += 1
update()
func newline():
history.push_back("")
update()
func add_input(text: String):
input += text
if text == " ":
cursor_pos.x += char_width * tab_width
else:
cursor_pos.x += char_width
update()
var helpcount = 0
func exec(cmd: String):
var file_data: String = fs.read("/bin/" + cmd)
if file_data == "":
add_text("Command not found: " + cmd)
else:
if cmd == "help":
helpcount += 1
if helpcount > 3:
add_text("Bro are you ok?")
else:
for line in file_data.split("\n"):
add_text(line)
func welcome():
var title = """
@@@@@@ @@@@@@@@@@ @@@@@@@@ @@@ @@@ @@@@@@ @@@@@@
@@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@ @@@ @@@@@@@@ @@@@@@@
@@! @@@ @@! @@! @@! @@! @@!@!@@@ @@! @@@ !@@
!@! @!@ !@! !@! !@! !@! !@!!@!@! !@! @!@ !@!
@!@ !@! @!! !!@ @!@ @!!!:! @!@ !!@! @!@ !@! !!@@!!
!@! !!! !@! ! !@! !!!!!: !@! !!! !@! !!! !!@!!!
!!: !!! !!: !!: !!: !!: !!! !!: !!! !:!
:!: !:! :!: :!: :!: :!: !:! :!: !:! !:!
:::::::: ::: :: :: :::: :: :: :::::::: :::: ::
:::::: : : : :: :: :: : :::::: :: : :
"""
for line in title.split("\n", false):
add_text(VIOLET + line)
newline()
newline()
add_text(RED + "Welcome to Omen OS . . .")
newline()
newline()
add_text(GRAY + "\"Hidden in distant wastes and dark places all over the world until the time")
add_text(GRAY + "when the great priest Cthulhu, from his dark house in the mighty city of R'lyeh")
add_text(GRAY + "under the waters, should rise and bring the earth again beneath his sway\"")
newline()
newline()
add_text(GRAY + "---------------------------------")
newline()
newline()
add_text(WHITE + "Type " + GREEN + "'help'" + WHITE + " for command info")
newline()
newline()
func _ready():
window_height = get_size().y
line_height = font.get_height()
char_width = font.get_string_size("@").x
cursor_size = Vector2(char_width, line_height)
reset_cursor()
welcome()
var fs = FileSystem.new()
fs.bootstrap()
func _physics_process(delta):
tick += 1
if tick % 22 == 0:
show_cursor = !show_cursor
update()
func _input(event):
if event is InputEventKey and event.pressed:
var shift = Input.is_key_pressed(KEY_SHIFT)
match event.scancode:
KEY_SPACE:
add_input(" ")
KEY_PERIOD:
add_input(".")
KEY_COMMA:
add_input(",")
KEY_COLON:
add_input(":")
KEY_SEMICOLON:
if shift:
add_input(":")
else:
add_input(";")
KEY_SLASH:
if shift:
add_input("?")
else:
add_input("/")
KEY_BACKSLASH:
if shift:
add_input("|")
else:
add_input("\\")
KEY_TAB:
add_input(" ")
KEY_CONTROL, KEY_SHIFT, KEY_ALT, KEY_SUPER_L, KEY_SUPER_R, KEY_META:
pass
KEY_BACKSPACE:
if input.length() > 0:
var last_char = input[input.length() - 1]
if last_char == " ":
cursor_pos.x -= char_width * tab_width
else:
cursor_pos.x -= char_width
input = input.substr(0, input.length() - 1)
update()
KEY_ENTER:
if input.length() > 0:
history.push_back(ps1 + input)
exec(input)
input = ""
if history.size() > get_max_lines():
scroll_y += 1
reset_cursor()
update()
_: # DEFAULT
var key_string = OS.get_scancode_string(event.scancode)
if shift:
add_input(key_string)
else:
add_input(key_string.to_lower())
func _draw():
var y = line_height
var color = Color.whitesmoke
# Draw output history
for text in history.slice(scroll_y, scroll_y + get_max_lines()):
draw_text_line(text, y)
y += line_height
# Draw input line
draw_text_line(ps1 + input, y)
# Draw cursor
if show_cursor:
draw_rect(
Rect2(Vector2(cursor_pos.x, (history.size() - scroll_y) * line_height + 2), cursor_size),
Color.whitesmoke)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment