Mercurial > repo
view interps/cfunge/cfunge-src/src/fingerprints/NCRS/NCRS.c @ 12518:2d8fe55c6e65 draft default tip
<int-e> learn The password of the month is release incident pilot.
author | HackEso <hackeso@esolangs.org> |
---|---|
date | Sun, 03 Nov 2024 00:31:02 +0000 |
parents | 859f9b4339e6 |
children |
line wrap: on
line source
/* -*- mode: C; coding: utf-8; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- * * cfunge - A standard-conforming Befunge93/98/109 interpreter in C. * Copyright (C) 2008-2009 Arvid Norlander <anmaster AT tele2 DOT se> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at the proxy's option) any later version. Arvid Norlander is a * proxy who can decide which future versions of the GNU General Public * License can be used. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #define FUNGE_EXTENDS_NCRS #define FUNGE_EXTENDS_TERM #include "NCRS.h" #if defined(HAVE_NCURSES) #include "../../stack.h" #include <stdio.h> #include "../TERM/TERM.h" #include <ncurses.h> #include <term.h> #if defined(__OpenBSD__) // OpenBSD's ncurses sucks hard, it redefines bool. # undef bool # define bool _Bool #endif #define NCRS_VALIDATE_STATE() if (!ncrs_valid_state) { ip_reverse(ip); return; } /// Defines if we have ever ncrs_initialised. static bool ncrs_initialised = false; /// Defines if we have a valid ncrs_initialised state. static bool ncrs_valid_state = false; static SCREEN* ncrs_screen = NULL; static WINDOW* ncrs_window = NULL; /// For use from TERM FUNGE_ATTR_FAST bool finger_NCRS_need_setupterm(void) { return !ncrs_valid_state; } /// B - Beep static void finger_NCRS_beep(instructionPointer * ip) { NCRS_VALIDATE_STATE(); if (beep() == ERR) ip_reverse(ip); } /// C - Clear all or part of the screen static void finger_NCRS_clear(instructionPointer * ip) { funge_cell value = stack_pop(ip->stack); NCRS_VALIDATE_STATE(); switch (value) { case 0: if (werase(ncrs_window) == ERR) ip_reverse(ip); return; case 1: if (wclrtoeol(ncrs_window) == ERR) ip_reverse(ip); return; case 2: if (wclrtobot(ncrs_window) == ERR) ip_reverse(ip); return; default: ip_reverse(ip); } } /// E - Set echo mode static void finger_NCRS_toggle_echo(instructionPointer * ip) { funge_cell value = stack_pop(ip->stack); NCRS_VALIDATE_STATE(); switch (value) { case 0: if (noecho() == ERR) ip_reverse(ip); return; case 1: if (echo() == ERR) ip_reverse(ip); return; default: ip_reverse(ip); } } /// G - Get character static void finger_NCRS_get(instructionPointer * ip) { funge_cell value; NCRS_VALIDATE_STATE(); if ((value = wgetch(ncrs_window)) == ERR) ip_reverse(ip); else stack_push(ip->stack, (funge_cell)value); } /// I - Initialise and end curses mode static void finger_NCRS_init(instructionPointer * ip) { if (stack_pop(ip->stack) == 1) { // We can only initialise once per session. if (!ncrs_initialised) { // If TERM was used before, check to make sure we don't get a mem // leak: finger_TERM_fix_before_NCRS_init(); ncrs_screen = newterm(NULL, stdout, stdin); if (!ncrs_screen) goto error; set_term(ncrs_screen); ncrs_window = newwin(0, 0, 0, 0); if (!ncrs_window) goto error; stdscr = ncrs_window; ncrs_initialised = true; ncrs_valid_state = true; } else { goto error; } } else { if (!ncrs_initialised) goto error; if (endwin() == ERR) goto error; if (delwin(ncrs_window) == ERR) goto error; delscreen(ncrs_screen); ncrs_screen = NULL; ncrs_window = NULL; ncrs_valid_state = false; // If TERM was used before, fix up the issues: finger_TERM_fix_after_NCRS_teardown(); } return; error: ip_reverse(ip); ncrs_valid_state = false; } /// K - Set keypad mode static void finger_NCRS_toggle_keypad(instructionPointer * ip) { funge_cell value = stack_pop(ip->stack); NCRS_VALIDATE_STATE(); switch (value) { case 0: if (keypad(stdscr, false) == ERR) ip_reverse(ip); return; case 1: if (keypad(stdscr, true) == ERR) ip_reverse(ip); return; default: ip_reverse(ip); } } /// M - Move cursor to x,y static void finger_NCRS_goto_xy(instructionPointer * ip) { funge_vector v = stack_pop_vector(ip->stack); NCRS_VALIDATE_STATE(); if (wmove(ncrs_window, (int)v.y, (int)v.x) == ERR) ip_reverse(ip); } /// N - Toggle input mode static void finger_NCRS_toggle_input(instructionPointer * ip) { funge_cell value = stack_pop(ip->stack); NCRS_VALIDATE_STATE(); switch (value) { case 0: if (cbreak() == ERR) ip_reverse(ip); return; case 1: if (nocbreak() == ERR) ip_reverse(ip); return; default: ip_reverse(ip); } } /// P - Put the character at cursor static void finger_NCRS_put(instructionPointer * ip) { funge_cell value = stack_pop(ip->stack); NCRS_VALIDATE_STATE(); if (waddch(ncrs_window, (chtype)value) == ERR) ip_reverse(ip); } /// R - Refresh window static void finger_NCRS_refresh(instructionPointer * ip) { NCRS_VALIDATE_STATE(); if (refresh() == ERR) ip_reverse(ip); } /// S - Write string at cursor static void finger_NCRS_write(instructionPointer * ip) { unsigned char* str = stack_pop_string(ip->stack, NULL); NCRS_VALIDATE_STATE(); if (waddstr(ncrs_window, (char*)str) == ERR) ip_reverse(ip); stack_free_string(str); } /// U - Unget character static void finger_NCRS_unget(instructionPointer * ip) { funge_cell value = stack_pop(ip->stack); NCRS_VALIDATE_STATE(); if (ungetch((chtype)value) == ERR) ip_reverse(ip); } bool finger_NCRS_load(instructionPointer * ip) { manager_add_opcode(NCRS, 'B', beep) manager_add_opcode(NCRS, 'C', clear) manager_add_opcode(NCRS, 'E', toggle_echo) manager_add_opcode(NCRS, 'G', get) manager_add_opcode(NCRS, 'I', init) manager_add_opcode(NCRS, 'K', toggle_keypad) manager_add_opcode(NCRS, 'M', goto_xy) manager_add_opcode(NCRS, 'N', toggle_input) manager_add_opcode(NCRS, 'P', put) manager_add_opcode(NCRS, 'R', refresh) manager_add_opcode(NCRS, 'S', write) manager_add_opcode(NCRS, 'U', unget) return true; } #endif /* defined(HAVE_NCURSES) */