module console
var _input_queue_index: byte
var _row: byte
var _col: byte
var _pos: pair
var _color_addend: pair
var _blink_save: pair
var _blink: bool
var cursor_visible: bool
var scroll_off: bool
var reverse: bool
var matte: bool
var ctrl_key: bool
func init(io_tilemap: io_tilemap)
io::input_queue_end_index -> console::_input_queue_index
1024 -> console::_color_addend
console::_print_char('{cls}')
64 -> io_tilemap.col_count
32 -> io_tilemap.row_count
to_address(kernel::console_grid) -> io_tilemap.tile_codes_address
end func
func _blink_off()
if console::_blink then
false -> console::_blink
console::_blink_save -> kernel::console_grid[console::_pos]
end if
end func
func _blink_restore()
if console::cursor_visible then
true -> console::_blink
var c: pair
kernel::console_grid[console::_pos] -> c
c -> console::_blink_save
to_pair(math::bit_and(c, $3ff)) -> c
to_pair(c + console::_color_addend) -> c
to_pair(math::bit_xor(c, $4000)) -> c
c -> kernel::console_grid[console::_pos]
end if
end func
func set_color(color: int)
console::_blink_off()
if color < 0 or color > 15
do kernel::fail("set_color() invalid color")
to_pair(color * 1024) -> console::_color_addend
console::_blink_restore()
end func
func print(s: string)
console::_print(s, s.size)
end func
func print_text(text: text)
console::_print(text._chars, text.length)
end func
func _print(text: char[], size: int)
console::_blink_off()
var i: int
0 -> i
loop
if i >= size
do drop
var c: pair
text[i] -> c
console::_print_char(c)
i + 1 -> i
end loop
console::_blink_restore()
end func
func print_int(n: int)
console::_blink_off()
var c: int
n -> c
if n < 0 then
console::print_char('-')
else
-c -> c
end if
var i: int, digit: int
0 -> i
loop
-(c % 10) -> digit
to_byte(48 + digit) -> unsafe(kernel::scratch_bytes)[i]
c / 10 -> c
if c = 0
do drop
i + 1 -> i
end loop
loop
console::_print_char(kernel::scratch_bytes[i])
i <- i - 1
if i < 0
do drop
end loop
console::_blink_restore()
end func
func print_char(c: pair)
console::_blink_off()
console::_print_char(c)
console::_blink_restore()
end func
func _print_char(c: pair)
var col: byte
var row: byte
var pos: pair
console::_col -> col
console::_row -> row
console::_pos -> pos
if c < 0
do to_pair(c + 256) -> c
if c < 32 then
if c = '{reset}' then
false -> console::scroll_off
false -> console::reverse
false -> console::matte
elsif c = '{soff}' then
true -> console::scroll_off
elsif c = '{sup}' then
console::_scroll_up()
elsif c = '{sdown}' then
kernel::copy_memory_bytes(
| to_address(kernel::console_grid) + 128,
| to_address(kernel::console_grid),
| 3456)
kernel::set_memory_pairs(
| to_address(kernel::console_grid),
| 32,
| 40)
elsif c = '{cls}' then
kernel::set_memory_pairs(
| to_address(kernel::console_grid),
| ' ',
| 1792)
0 -> pos
0 -> col
0 -> row
elsif c = '{cll}' then
to_pair(pos - col) -> pos
0 -> col
kernel::set_memory_pairs(
| to_address(kernel::console_grid) + pos * 2,
| ' ',
| 40)
elsif c = '{tab}' then
var tab_amount: int
8 - to_byte(math::bit_and(col, 7)) -> tab_amount
to_byte(col + tab_amount) -> col
to_pair(pos + tab_amount) -> pos
if col >= 40 then
to_pair(pos - col + 64) -> pos
0 -> col
to_byte(row + 1) -> row
end if
elsif c = '{n}' then
to_pair(pos - col + 64) -> pos
0 -> col
to_byte(row + 1) -> row
elsif c = '{home}' then
0 -> pos
0 -> col
0 -> row
elsif c = '{end}' then
1728 -> pos
0 -> col
27 -> row
elsif c = '{cr}' then
to_pair(pos - col) -> pos
0 -> col
elsif c = '{rev}' then
true -> console::reverse
elsif c = 15 then
true -> console::matte
elsif c >= 16 and c <= 25 then
to_pair((c - 16) * 1024) -> console::_color_addend
elsif c = '{u}' then
if row > 0 then
to_pair(pos - 64) -> pos
to_byte(row - 1) -> row
end if
elsif c = '{d}' then
to_pair(pos + 64) -> pos
to_byte(row + 1) -> row
elsif c = '{l}' then
if col > 0 then
to_pair(pos - 1) -> pos
to_byte(col - 1) -> col
else
if row > 0 then
to_pair(pos - col - (64 - 39)) -> pos
39 -> col
to_byte(row - 1) -> row
end if
end if
elsif c = '{r}' then
if col < 39 then
to_pair(pos + 1) -> pos
to_byte(col + 1) -> col
else
to_pair(pos - col + 64) -> pos
0 -> col
to_byte(row + 1) -> row
end if
end if
else
var p: pair
to_pair(c + console::_color_addend) -> p
if console::reverse then
to_pair(math::bit_or(p, $4000)) -> p
end if
if console::matte then
to_pair(math::bit_or(p, $8000)) -> p
end if
p -> kernel::console_grid[pos]
if col < 39 then
to_pair(pos + 1) -> pos
to_byte(col + 1) -> col
else
to_pair(pos - col + 64) -> pos
0 -> col
to_byte(row + 1) -> row
end if
end if
if row >= 28 then
to_byte(row - 1) -> row
to_pair(pos - 64) -> pos
if not console::scroll_off then
console::_scroll_up()
end if
end if
col -> console::_col
row -> console::_row
pos -> console::_pos
end func
func _scroll_up()
kernel::copy_memory_bytes(
| to_address(kernel::console_grid),
| to_address(kernel::console_grid) + 128,
| 3456)
kernel::set_memory_pairs(
| to_address(kernel::console_grid) + 3456,
| ' ',
| 40)
end func
func read_key(): byte
var index: byte, end_index: byte
var result: byte
io::input_queue_end_index -> end_index
console::_input_queue_index -> index
0 -> result
loop
if index = end_index
do drop
var event: ^io_input_event
io::input_queue[index] -> event
to_byte(index + 1) -> index
if index >= 16
do 0 -> index
var event_kind: byte, event_keyid: byte
event.kind -> event_kind
event.keyid -> event_keyid
if event_kind = 0 or event_kind = 1 then
if event_keyid = 18 or event_keyid = 19 then
true -> console::ctrl_key
elsif event.hascii > 0 and event.hascii < 256 then
to_byte(event.hascii) -> result
drop
end if
else
if event_keyid = 18 or event_keyid = 19 then
false -> console::ctrl_key
end if
end if
end loop
index -> console::_input_queue_index
return result
end func
func get_bookmark(): pair
return console::_pos
end func
func goto_bookmark(bookmark: pair)
if bookmark >= 1792
do kernel::fail("invalid bookmark")
console::_blink_off()
to_byte(math::shift_right_unsigned(bookmark, 6)) -> console::_row
to_byte(math::bit_and(bookmark, 63)) -> console::_col
bookmark -> console::_pos
console::_blink_restore()
end func
func think()
var blink_counter: int
math::bit_and(io::frame_counter, 31) -> blink_counter
if not console::cursor_visible or blink_counter >= 16 then
console::_blink_off()
else
if not console::_blink then
true -> console::_blink
console::_blink_restore()
end if
end if
end func
end module