🎨 fix a bug in module/keyboard.cpp that if program exited with an error, the terminal may not echo the text you input
This commit is contained in:
parent
07eeaadf96
commit
dcad554eba
|
@ -7,68 +7,77 @@
|
|||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
class noecho_input{
|
||||
private:
|
||||
#ifndef _WIN32
|
||||
static struct termios init_termios;
|
||||
static struct termios new_termios;
|
||||
static int peek_char=-1;
|
||||
|
||||
int kbhit(){
|
||||
unsigned char ch=0;
|
||||
int nread=0;
|
||||
if(peek_char!=-1)
|
||||
return 1;
|
||||
int flag=fcntl(0,F_GETFL);
|
||||
fcntl(0,F_SETFL,flag|O_NONBLOCK);
|
||||
nread=read(0,&ch,1);
|
||||
fcntl(0,F_SETFL,flag);
|
||||
if(nread==1){
|
||||
peek_char=ch;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getch(){
|
||||
int ch=0;
|
||||
if(peek_char!=-1){
|
||||
ch=peek_char;
|
||||
peek_char=-1;
|
||||
return ch;
|
||||
}
|
||||
read(0,&ch,1);
|
||||
return ch;
|
||||
}
|
||||
struct termios init_termios;
|
||||
struct termios new_termios;
|
||||
int peek_char=-1;
|
||||
#endif
|
||||
public:
|
||||
noecho_input(){
|
||||
#ifndef _WIN32
|
||||
tcflush(0,TCIOFLUSH);
|
||||
tcgetattr(0,&init_termios);
|
||||
new_termios=init_termios;
|
||||
new_termios.c_lflag&=~(ICANON|ECHO|ECHONL|ECHOE);
|
||||
// vmin=0 is nonblock input, but in wsl there is a bug that will block input
|
||||
// so we use fcntl to write the nonblock input
|
||||
new_termios.c_cc[VMIN]=1;
|
||||
new_termios.c_cc[VTIME]=0;
|
||||
tcsetattr(0,TCSANOW,&new_termios);
|
||||
#endif
|
||||
}
|
||||
~noecho_input(){
|
||||
#ifndef _WIN32
|
||||
tcflush(0,TCIOFLUSH);
|
||||
tcsetattr(0,TCSANOW,&init_termios);
|
||||
#endif
|
||||
}
|
||||
int noecho_kbhit(){
|
||||
#ifndef _WIN32
|
||||
unsigned char ch=0;
|
||||
int nread=0;
|
||||
if(peek_char!=-1)
|
||||
return 1;
|
||||
int flag=fcntl(0,F_GETFL);
|
||||
fcntl(0,F_SETFL,flag|O_NONBLOCK);
|
||||
nread=read(0,&ch,1);
|
||||
fcntl(0,F_SETFL,flag);
|
||||
if(nread==1){
|
||||
peek_char=ch;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return kbhit();
|
||||
#endif
|
||||
}
|
||||
int noecho_getch(){
|
||||
#ifndef _WIN32
|
||||
int ch=0;
|
||||
if(peek_char!=-1){
|
||||
ch=peek_char;
|
||||
peek_char=-1;
|
||||
return ch;
|
||||
}
|
||||
read(0,&ch,1);
|
||||
return ch;
|
||||
#else
|
||||
return getch();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
noecho_input this_window;
|
||||
extern "C" nasal_ref nas_getch(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
return {vm_num,(double)getch()};
|
||||
return {vm_num,(double)this_window.noecho_getch()};
|
||||
}
|
||||
extern "C" nasal_ref nas_kbhit(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
return {vm_num,(double)kbhit()};
|
||||
return {vm_num,(double)this_window.noecho_kbhit()};
|
||||
}
|
||||
extern "C" nasal_ref nas_noblock(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
if(kbhit())
|
||||
return {vm_num,(double)getch()};
|
||||
return nil;
|
||||
}
|
||||
extern "C" nasal_ref nas_init(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
#ifndef _WIN32
|
||||
tcflush(0,TCIOFLUSH);
|
||||
tcgetattr(0,&init_termios);
|
||||
new_termios=init_termios;
|
||||
new_termios.c_lflag&=~(ICANON|ECHO|ECHONL|ECHOE);
|
||||
// vmin=0 is nonblock input, but in wsl there is a bug that will block input
|
||||
// so we use fcntl to write the nonblock input
|
||||
new_termios.c_cc[VMIN]=1;
|
||||
new_termios.c_cc[VTIME]=0;
|
||||
tcsetattr(0,TCSANOW,&new_termios);
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
extern "C" nasal_ref nas_close(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
#ifndef _WIN32
|
||||
tcflush(0,TCIOFLUSH);
|
||||
tcsetattr(0,TCSANOW,&init_termios);
|
||||
#endif
|
||||
if(this_window.noecho_kbhit())
|
||||
return {vm_num,(double)this_window.noecho_getch()};
|
||||
return nil;
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
import("lib.nas");
|
||||
|
||||
var libfib=func(){
|
||||
var dl=dylib.dlopen("./module/libfib."~(os.platform()=="windows"?"dll":"so"));
|
||||
var fib=dylib.dlsym(dl,"fib");
|
||||
|
|
|
@ -1,47 +1,12 @@
|
|||
import("lib.nas");
|
||||
|
||||
var libkey=func(){
|
||||
var lib=dylib.dlopen("./module/libkey"~(os.platform()=="windows"?".dll":".so"));
|
||||
var kb=dylib.dlsym(lib,"nas_kbhit");
|
||||
var gt=dylib.dlsym(lib,"nas_getch");
|
||||
var nb=dylib.dlsym(lib,"nas_noblock");
|
||||
var init=dylib.dlsym(lib,"nas_init");
|
||||
var cls=dylib.dlsym(lib,"nas_close");
|
||||
var call=dylib.dlcall;
|
||||
var is_init=0;
|
||||
return {
|
||||
init:func(){
|
||||
# change io mode to no echo
|
||||
call(init);
|
||||
is_init=1;
|
||||
},
|
||||
kbhit:func(){
|
||||
# check if kerboard is hit
|
||||
# if keyboard is hit this function will return 1
|
||||
# until getch() gets all the input characters
|
||||
# and the input flow becomes empty
|
||||
if(!is_init)
|
||||
me.init();
|
||||
return call(kb);
|
||||
},
|
||||
getch:func(){
|
||||
# get input one character without echo
|
||||
# block until get one input
|
||||
if(!is_init)
|
||||
me.init();
|
||||
return call(gt);
|
||||
},
|
||||
nonblock:func(){
|
||||
# nonblock input without echo
|
||||
if(!is_init)
|
||||
me.init();
|
||||
return call(nb);
|
||||
},
|
||||
close:func(){
|
||||
# must call this function before exiting the program
|
||||
# this will change terminal mode to normal io mode
|
||||
call(cls);
|
||||
dylib.dlclose(lib);
|
||||
}
|
||||
kbhit:func(){return call(kb);},
|
||||
getch:func(){return call(gt);},
|
||||
nonblock:func(){return call(nb);}
|
||||
}
|
||||
}();
|
|
@ -178,7 +178,7 @@ var main=func(){
|
|||
if(os.platform()=="windows")
|
||||
system("chcp 65001");
|
||||
print("\ec");
|
||||
libkey.init();
|
||||
|
||||
var g=game(15,10);
|
||||
g.print();
|
||||
print("\rpress any key to start...");
|
||||
|
@ -207,10 +207,10 @@ var main=func(){
|
|||
g.print();
|
||||
}
|
||||
}
|
||||
libkey.close();
|
||||
|
||||
println(g.gameover()<=1?"game over.":"you win!");
|
||||
println("enter anything to quit.");
|
||||
input();
|
||||
println("press 'q' to quit.");
|
||||
while(libkey.getch()!='q'[0]);
|
||||
}
|
||||
|
||||
main();
|
|
@ -275,7 +275,6 @@ var main=func(){
|
|||
if(os.platform()=="windows")
|
||||
system("chcp 65001");
|
||||
|
||||
libkey.init();
|
||||
print(
|
||||
"\ec\e[1:1H",
|
||||
"╔═════════════════════════╗\n",
|
||||
|
@ -331,7 +330,7 @@ var main=func(){
|
|||
unix.sleep(0.02);
|
||||
counter-=1;
|
||||
}
|
||||
libkey.close();
|
||||
|
||||
print(
|
||||
map.gameover()?
|
||||
"\e[31mg\e[32ma\e[33mm\e[34me \e[35mo\e[36mv\e[94me\e[31mr \e[32m~\e[0m\n":
|
||||
|
@ -339,10 +338,10 @@ var main=func(){
|
|||
);
|
||||
print(
|
||||
"\e[31me\e[32mn\e[33mt\e[34me\e[35mr ",
|
||||
"\e[36ma\e[94mn\e[95my\e[96mt\e[31mh\e[32mi\e[33mn\e[34mg ",
|
||||
"\e[36m'\e[94mq\e[95m' ",
|
||||
"\e[35mt\e[36mo \e[94mq\e[95mu\e[91mi\e[92mt\e[0m\n"
|
||||
);
|
||||
input();
|
||||
while(libkey.getch()!='q'[0]);
|
||||
};
|
||||
|
||||
main();
|
Loading…
Reference in New Issue