From b94ebe30c899b61fcf01039c7a57e69133db62d3 Mon Sep 17 00:00:00 2001 From: PoliEcho Date: Thu, 10 Jul 2025 18:27:52 +0200 Subject: [PATCH] add user input handling --- src/drawing.asm | 25 +++++++-- src/input.asm | 135 ++++++++++++++++++++++++++++++++++++++++++++++-- src/main.asm | 8 +++ src/symbols.asm | 8 +++ 4 files changed, 169 insertions(+), 7 deletions(-) diff --git a/src/drawing.asm b/src/drawing.asm index f5dfb06..738bdd4 100644 --- a/src/drawing.asm +++ b/src/drawing.asm @@ -9,7 +9,8 @@ section .bss extern term_cols extern gameboard_size - + + global simulation_running simulation_running: RESB 1 section .rodata @@ -20,8 +21,8 @@ section .rodata home_cursor: db ESC_CHAR, "[H", 0 - statusbar: db ESC_CHAR, "[30;100m", "Use arrow keys to move cursor, enter to invert cell h/j to change simulation speed, p to simulation", 0 - START_STOP_pos: equ $-statusbar-16 + statusbar: db ESC_CHAR, "[30;100m", "Use arrow keys to move cursor, enter to invert cell j/k to change simulation speed, p to simulation", 0 + START_STOP_pos: equ $-statusbar-17 start_str: db "START", 0 @@ -68,8 +69,24 @@ global print_game_ui print_game_ui: lea rdi, [home_cursor] call print_str - + mov qword rdi, [gameboard_ptr] + push rdi + add rdi, [gameboard_size] + sub di, [term_cols] + add rdi, START_STOP_pos + + mov cl, [simulation_running] + test cl,cl; test if simulation is running + jz .simulation_not_running + lea rsi, [stop_str] + jmp .end_simulation_running_check + .simulation_not_running: + lea rsi, [start_str] + .end_simulation_running_check: + call string_copy + + pop rdi call print_str diff --git a/src/input.asm b/src/input.asm index 8dbf484..48826ad 100644 --- a/src/input.asm +++ b/src/input.asm @@ -1,12 +1,141 @@ +%include "symbols.asm" section .bss - cursor_rows: RESW 1 + cursor_rows: RESW 1; TODO DONT FORGET TO INICIALIZE cursor_cols: RESW 1 + extern multipurpuse_buf + + extern term_rows + extern term_cols + + extern gameboard_ptr + + extern simulation_running + +section .rodata + + cursor_up: db ESC_CHAR, "[1A", 0 + cursor_down: db ESC_CHAR, "[1B", 0 + cursor_right: db ESC_CHAR, "[1C", 0 + cursor_left: db ESC_CHAR, "[1D", 0 + + + arrow_switch_statement: + dq handle_user_input.arrow_up + dq handle_user_input.arrow_down + dq handle_user_input.arrow_right + dq handle_user_input.arrow_left + section .text -global handle_user_input -handle_user_input: +extern print_str +global handle_user_input +handle_user_input:; main loop of the program + + .main_loop: + + xor rax, rax + mov qword [multipurpuse_buf], rax; zeroout the buffer + + mov rax, SYS_POLL + mov rdi, STDIN + mov rsi, 1; only one file descriptor is provided + mov rdx, 0; no timeout. maybe use this for final sleep but run if user inputs something TODO + syscall + + test rax, rax; SYS_POLL returns 0 when no change happens within timeout + jz .no_input + + mov rax, SYS_READ + mov rdi, STDIN + lea rsi, [multipurpuse_buf] + mov rdx, 8; size of multipurpuse buffer + syscall; read user input + + mov rax, [multipurpuse_buf] + shr rax, 5; we need only 3 bytes for this inpus sceame + + cmp eax, 0x001B5B44; check if input is more than left arrow + ja .handle_single_byte_chars + + sub eax, 0x1B5B41 + jmp [arrow_switch_statement+(rax*8)]; lets hope this works + + .arrow_up: + dec word [cursor_rows] + lea rdi, [cursor_up] + call print_str + jmp .no_input + .arrow_down: + inc word [cursor_rows] + lea rdi, [cursor_down] + call print_str + jmp .no_input + .arrow_right: + inc word [cursor_cols] + lea rdi, [cursor_right] + call print_str + jmp .no_input + .arrow_left: + dec word [cursor_cols] + lea rdi, [cursor_left] + call print_str + jmp .no_input + + .handle_single_byte_chars: + + shr eax, 2; get the char to al + + cmp al, 0xa; NEWLINE (enter key) + jne .check_p + + xor rax, rax; zeroout rax + mov ax, [cursor_rows] + mul dword [term_cols] + add rax, [cursor_cols] + + lea rdi, [gameboard_ptr+rax] + mov cl, [rdi] + cmp cl, '#' + je .hashtag_present + + mov byte [rdi], '#' + jmp .no_input + + .hashtag_present: + + mov byte [rdi], ' ' + jmp .no_input + + .check_p: + cmp al, 'p' + jne .check_j + + xor byte [simulation_running], 0x01; switch simulation on or off + + jmp .no_input + + .check_j: + cmp al, 'j' + jne .check_k + + ; TODO implement simulation speed + + jmp .no_input + + .check_k: + cmp al, 'k' + jne .no_input + + ; TODO implement simulation speed + + .no_input: + + + jmp .main_loop + + ret diff --git a/src/main.asm b/src/main.asm index 61f6fce..d46a2dd 100644 --- a/src/main.asm +++ b/src/main.asm @@ -3,6 +3,7 @@ section .bss + global multipurpuse_buf multipurpuse_buf: RESB 8 global term_rows @@ -72,6 +73,13 @@ _start: mov [gameboard_ptr], rax; stores pointer to gameboard array call init_gameboard + ; make stdin non-blocking in case polling somehow fails, or am i stupid + mov rax, SYS_FCNTL + mov rdi, STDIN + mov rsi, F_SETFL + mov rdx, O_NONBLOCK + syscall + call print_game_ui diff --git a/src/symbols.asm b/src/symbols.asm index f184145..b34649b 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -1,10 +1,18 @@ SYS_EXIT equ 60 SYS_IOCTL equ 16 +SYS_READ equ 0 SYS_WRITE equ 1 SYS_BRK equ 12 +SYS_FCNTL equ 72 +SYS_POLL equ 7 +STDIN equ 0 STDOUT equ 1 + TIOCGWINSZ equ 0x5413 +POLLIN equ 1 +F_SETFL equ 4 +O_NONBLOCK equ 2048 ASCII_ZERO equ 48 ESC_CHAR equ 27