/** * Furnace Tracker - multi-system chiptune tracker * Copyright (C) 2021-2023 tildearrow and contributors * * 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 2 of the License, or * (at your option) any later version. * * 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "cli.h" #include "../ta-log.h" bool cliQuit=false; #ifndef _WIN32 static void handleTerm(int) { cliQuit=true; } #endif void FurnaceCLI::bindEngine(DivEngine* eng) { e=eng; } bool FurnaceCLI::loop() { bool escape=false; bool escapeSecondStage=false; while (!cliQuit) { #ifdef _WIN32 int c; c=fgetc(stdin); if (c==EOF) break; #else unsigned char c; if (read(STDIN_FILENO,&c,1)<=0) continue; #endif if (escape) { if (escapeSecondStage) { switch (c) { case 'C': // right e->setOrder(e->getOrder()+1); escape=false; escapeSecondStage=false; break; case 'D': // left e->setOrder(e->getOrder()-1); escape=false; escapeSecondStage=false; break; default: escape=false; escapeSecondStage=false; break; } } else { switch (c) { case '[': case 'O': escapeSecondStage=true; break; default: escape=false; break; } } } else { switch (c) { case 0x1b: // escape=true; break; case 'h': // left e->setOrder(e->getOrder()-1); break; case 'l': // right e->setOrder(e->getOrder()+1); break; case ' ': if (e->isHalted()) { e->resume(); } else { e->halt(); } break; } } } printf("\n"); return true; } bool FurnaceCLI::finish() { #ifdef _WIN32 #else if (tcsetattr(0,TCSAFLUSH,&termpropold)!=0) { logE("could not set console attributes!"); logE("you may have to run `reset` on your terminal."); return false; } #endif return true; } // blatantly copied from tildearrow/tfmxplay bool FurnaceCLI::init() { #ifdef _WIN32 winin=GetStdHandle(STD_INPUT_HANDLE); winout=GetStdHandle(STD_OUTPUT_HANDLE); int termprop=0; int termpropi=0; GetConsoleMode(winout,(LPDWORD)&termprop); GetConsoleMode(winin,(LPDWORD)&termpropi); termprop|=ENABLE_VIRTUAL_TERMINAL_PROCESSING; termpropi&=~ENABLE_LINE_INPUT; SetConsoleMode(winout,termprop); SetConsoleMode(winin,termpropi); #else sigemptyset(&intsa.sa_mask); intsa.sa_flags=0; intsa.sa_handler=handleTerm; sigaction(SIGINT,&intsa,NULL); if (tcgetattr(0,&termprop)!=0) { logE("could not get console attributes!"); return false; } memcpy(&termpropold,&termprop,sizeof(struct termios)); termprop.c_lflag&=~ECHO; termprop.c_lflag&=~ICANON; if (tcsetattr(0,TCSAFLUSH,&termprop)!=0) { logE("could not set console attributes!"); return false; } #endif return true; } FurnaceCLI::FurnaceCLI(): e(NULL) { }