diff --git a/module/keyboard.cpp b/module/keyboard.cpp new file mode 100644 index 0000000..93242f4 --- /dev/null +++ b/module/keyboard.cpp @@ -0,0 +1,75 @@ +#include "../nasal.h" +#include +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +#ifndef _WIN32 +static struct termios init_termios; +static struct termios new_termios; +static int peek_character=-1; + +int kbhit(){ + unsigned char ch=0; + int nread=0; + if(peek_character!=-1) + return 1; + int flag=fcntl(0,F_GETFL); + flag|=O_NONBLOCK; + fcntl(0,F_SETFL,flag); + nread=read(0,&ch,1); + flag&=(~O_NONBLOCK); + fcntl(0,F_SETFL,flag); + if(nread==1) + { + peek_character=ch; + return 1; + } + return 0; +} + +int getch(){ + int ch=0; + if(peek_character!=-1) + { + ch=peek_character; + peek_character=-1; + return ch; + } + read(0,&ch,1); + return ch; +} +#endif + +extern "C" nasal_ref nas_getch(std::vector& args,nasal_gc& gc){ + return {vm_num,(double)getch()}; +} +extern "C" nasal_ref nas_kbhit(std::vector& args,nasal_gc& gc){ + return {vm_num,(double)kbhit()}; +} +extern "C" nasal_ref nas_noblock(std::vector& args,nasal_gc& gc){ + if(kbhit()) + return {vm_num,(double)getch()}; + return nil; +} +extern "C" nasal_ref nas_init(std::vector& args,nasal_gc& gc){ +#ifndef _WIN32 + tcgetattr(0,&init_termios); + new_termios=init_termios; + new_termios.c_lflag&=~(ICANON|ECHO|ECHONL); + new_termios.c_cc[VMIN]=0; + new_termios.c_cc[VTIME]=0; + tcsetattr(0,TCSANOW,&new_termios); +#endif + return nil; +} +extern "C" nasal_ref nas_close(std::vector& args,nasal_gc& gc){ +#ifndef _WIN32 + tcsetattr(0,TCSANOW,&init_termios); + tcflush(0,TCIOFLUSH); +#endif + return nil; +} \ No newline at end of file diff --git a/module/libfib.nas b/module/libfib.nas new file mode 100644 index 0000000..d68b1b4 --- /dev/null +++ b/module/libfib.nas @@ -0,0 +1,13 @@ +import("lib.nas"); + +var libfib=func(){ + var dl=dylib.dlopen("./module/libfib."~(os.platform()=="windows"?"dll":"so")); + var fib=dylib.dlsym(dl,"fib"); + var qfib=dylib.dlsym(dl,"quick_fib"); + var call=dylib.dlcall; + return + { + fib: func(x){return call(fib,x)}, + qfib:func(x){return call(qfib,x)} + }; +}(); \ No newline at end of file diff --git a/module/libkey.nas b/module/libkey.nas new file mode 100644 index 0000000..ab0c769 --- /dev/null +++ b/module/libkey.nas @@ -0,0 +1,37 @@ +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 is_init=0; + return { + init:func(){ + dylib.dlcall(init); + is_init=1; + }, + kbhit:func(){ + if(!is_init) + me.init(); + return dylib.dlcall(kb); + }, + getch:func(){ + if(!is_init) + me.init(); + return dylib.dlcall(gt); + }, + nonblock:func(){ + if(!is_init) + me.init(); + return dylib.dlcall(nb); + }, + close:func(){ + # must call this function before exiting the program + dylib.dlcall(cls); + dylib.dlclose(lib); + } + } +}(); \ No newline at end of file diff --git a/module/makefile b/module/makefile index d1c545b..a175957 100644 --- a/module/makefile +++ b/module/makefile @@ -5,5 +5,11 @@ libfib.so: fib.cpp libfib.dll: fib.cpp g++ -c -O3 fib.cpp -fPIC -o fib.o g++ -shared -o libfib.dll fib.o +libkey.so: keyboard.cpp + clang++ -c -O3 keyboard.cpp -fPIC -o keyboard.o + clang++ -shared -o libkey.so keyboard.o +libkey.dll: keyboard.cpp + g++ -c -O3 keyboard.cpp -fPIC -o keyboard.o + g++ -shared -o libkey.dll keyboard.o clean: rm *.o *.so *.dll *.dylib \ No newline at end of file diff --git a/test/module_test.nas b/test/module_test.nas index b3502a5..fa48d22 100644 --- a/test/module_test.nas +++ b/test/module_test.nas @@ -1,16 +1,5 @@ import("lib.nas"); - -var libfib=func(){ - var dl=dylib.dlopen("./module/libfib."~(os.platform()=="windows"?"dll":"so")); - var fib=dylib.dlsym(dl,"fib"); - var qfib=dylib.dlsym(dl,"quick_fib"); - var call=dylib.dlcall; - return - { - fib: func(x){return call(fib,x)}, - qfib:func(x){return call(qfib,x)} - }; -}(); +import("./module/libfib.nas"); println(libfib); println(libfib.fib(29)); diff --git a/test/tetris.nas b/test/tetris.nas new file mode 100644 index 0000000..96b14a8 --- /dev/null +++ b/test/tetris.nas @@ -0,0 +1,58 @@ +import("lib.nas"); +import("module/libkey.nas"); + +var brick=[ + [ + [1,1], + [1,0], + [1,0] + ], + [ + [0,1], + [1,1], + [1,0] + ], + [ + [1,1], + [0,1], + [0,1], + ], + [ + [1,0], + [1,1], + [0,1] + ], + [ + [1,1,1,1] + ], + [ + [1,1], + [1,1] + ], + [ + [0,1,0], + [1,1,1] + ] +]; + +func(){ + libkey.init(); + print('\ec'); + var cnt=0; + while(1){ + var ch=libkey.nonblock(); + ch=ch?chr(ch)~chr(ch):"[]"; + var s="\ec+--------------+\n"; + var normal="| |\n"; + var character="| "~ch~" |\n"; + for(var i=0;i<6;i+=1) + s~=(i==cnt)?character:normal; + s~="+--------------+\n"; + print(s); + unix.sleep(0.3); + cnt+=1; + if(cnt==6) + cnt=0; + } + libkey.close(); +}(); \ No newline at end of file