diff --git a/pong.c b/pong.c new file mode 100644 index 0000000..addfd58 --- /dev/null +++ b/pong.c @@ -0,0 +1,200 @@ +/*******************\ +| Pong | +| | +| By Alnotz | +\*******************/ +/* +gcc -o pong pong.c `/usr/bin/pkg-config --libs --cflags ncurses` +*/ +#include +#include +/*Ncurses header*/ +#include +/*Inner window size*/ +#define LINE 40 +#define COL 80 +/*Inner window title & border*/ +#define DO_TITLE(void) \ + /*Inner border*/\ + box(inwin, '|', '-');\ + /*Inner window title*/\ + wmove(inwin, 0, COL/4);\ + wattron(inwin, COLOR_PAIR(2));\ + wprintw(inwin, "Push 'q' to quit");\ + wmove(inwin, 0, COL-11);\ + timespec_get(&ts, TIME_UTC);\ + strftime(buff, sizeof buff, "%H:%M\'%S\"", gmtime(&ts.tv_sec));\ + wprintw(inwin, "%s", buff);\ + wattroff(inwin, COLOR_PAIR(2)); +/*False asynchronization timer*/ +unsigned int tmr=0; +/*Inner window*/ +WINDOW *inwin; +/*Cursor position*/ +int bracket_Rl=LINE-1, bracket_Rc=COL/2, startl, startc; +/*Ball position*/ +int ball_Rl=LINE-2, ball_Rc=COL/2, ball_Vl=-1, ball_Vc=1; +/*Key number*/ +int ch; +/*Bloc array*/ +char blocs0[COL]; +/*Clock*/ +struct timespec ts; +char buff[20]; +void blocs_ltest(char *blc[], const int *ball_Rl, + const int *ball_Rc, int *ball_Vl) +{ + const size_t lsize = (sizeof *blc) / (sizeof *blc[0]); + if(*ball_Rl==1 || *ball_Rl==3 && *blc[*ball_Rc]=='#') + { + *blc[*ball_Rc]==' '; + *ball_Vl = -*ball_Vl; + } +} + +int ball_Vl_test(void) +{ + const int lwall = ball_Rl<1 || ball_Rl>LINE-2; + const int br_csize = ball_Rc>=bracket_Rc && ball_Rc0; + const int br_up = ball_Rl==bracket_Rl+1 && ball_Vl<0; + return lwall || (br_csize && br_bot) || (br_csize && br_up); +} +int ball_Vc_test(void) +{ + const int cwall = ball_Rc<1 || ball_Rc>COL-2; + const int br_lsize = ball_Rl==bracket_Rl; + const int br_left = ball_Rc==bracket_Rc-1 && ball_Vc>0; + const int br_right = ball_Rc==bracket_Rc+3 && ball_Vc<0; + return cwall || (br_lsize && br_left) || (br_lsize && br_right); +} +int main(int argc, char *argv[]) +{ + /*Outer window*/ + initscr(); + startl=LINES/2-LINE/2; + startc=COLS/2-COL/2; + /*Color enabled*/ + start_color(); + init_pair(1, COLOR_RED, COLOR_BLACK); + init_pair(2, COLOR_GREEN, COLOR_BLACK); + init_pair(3, COLOR_BLUE, COLOR_BLACK); + init_pair(4, COLOR_YELLOW, COLOR_BLACK); + /*Cursor hidden*/ + curs_set(0); + /*Inner window set*/ + inwin = newwin(LINE, COL, startl, startc); + /*Timeout enabled for wgetch*/ + wtimeout(inwin, 20); + /*Keypad enabled*/ + keypad(inwin, TRUE); + DO_TITLE() + /*Initial blocs*/ + for(int i=0; i3 && i<10) || (i>23 && i<30)) + { + blocs0[i]='#'; + } + else + { + blocs0[i]=' '; + } + } + /*First blocs position*/ + wmove(inwin, 2, 1); + /*Blocs in yellow*/ + wattron(inwin, COLOR_PAIR(4)); + wprintw(inwin, "%s", blocs0); + wattroff(inwin, COLOR_PAIR(4)); + /*First cursor position*/ + wmove(inwin, bracket_Rl, bracket_Rc); + /*Cursor in red*/ + wattron(inwin, COLOR_PAIR(1)); + wprintw(inwin, "###"); + wattroff(inwin, COLOR_PAIR(1)); + /*Ball in blue*/ + wmove(inwin, ball_Rl, ball_Rc); + wattron(inwin, COLOR_PAIR(3)); + wprintw(inwin, "O"); + wattroff(inwin, COLOR_PAIR(3)); + /*Inner window updated*/ + wrefresh(inwin); + /*Key expected*/ + ch = wgetch(inwin); + /*Inner window cleared before next update*/ + wclear(inwin); + while(ch!=(int)'q') + { + DO_TITLE() + /*First blocs position*/ + wmove(inwin, 2, 1); + /*Blocs in yellow*/ + wattron(inwin, COLOR_PAIR(4)); + wprintw(inwin, "%s", blocs0); + wattroff(inwin, COLOR_PAIR(4)); + /*Cursor movement*/ + switch(ch) + { + case KEY_RIGHT: + if(bracket_Rc==COL-3) + wmove(inwin, bracket_Rl, bracket_Rc); + else + wmove(inwin, bracket_Rl, ++bracket_Rc); + break; + case KEY_LEFT: + if(bracket_Rc==0) + wmove(inwin, bracket_Rl, bracket_Rc); + else + wmove(inwin, bracket_Rl, --bracket_Rc); + break; + case KEY_DOWN: + if(bracket_Rl==LINE-1) + wmove(inwin, bracket_Rl, bracket_Rc); + else + wmove(inwin, ++bracket_Rl, bracket_Rc); + break; + case KEY_UP: + if(bracket_Rl==0) + wmove(inwin, bracket_Rl, bracket_Rc); + else + wmove(inwin, --bracket_Rl, bracket_Rc); + break; + /*No key pushed*/ + case ERR: + wmove(inwin, bracket_Rl, bracket_Rc); + break; + } + wattron(inwin, COLOR_PAIR(1)); + wprintw(inwin, "###"); + wattroff(inwin, COLOR_PAIR(1)); + /*Ball movement*/ + if(tmr==4) + { + if(ball_Vl_test()) + { + ball_Vl=-ball_Vl; + } + if(ball_Vc_test()) + { + ball_Vc=-ball_Vc; + } + ball_Rl=ball_Rl+ball_Vl; + ball_Rc=ball_Rc+ball_Vc; + tmr=0; + } + else + { + tmr+=1; + } + wmove(inwin, ball_Rl, ball_Rc); + wattron(inwin, COLOR_PAIR(3)); + wprintw(inwin, "O"); + wattroff(inwin, COLOR_PAIR(3)); + wrefresh(inwin); + ch = wgetch(inwin); + wclear(inwin); + } + endwin(); + return EXIT_SUCCESS; +} diff --git a/pong_mthread.c b/pong_mthread.c new file mode 100644 index 0000000..8e70ca5 --- /dev/null +++ b/pong_mthread.c @@ -0,0 +1,119 @@ +/*******************\ +| Pong | +| | +| By Alnotz | +\*******************/ +/* +gcc -o pong_mthread pong_mthread.c `/usr/bin/pkg-config --libs --cflags ncurses` -pthread +*/ +#include +#include +#include +/*Ncurses header*/ +#include +/*Inner window size*/ +#define LINE 40 +#define COL 80 +/*Threads*/ +pthread_t bracket_th; +pthread_t ball_th; +/*Mutex*/ +pthread_mutex_t mtx; +/*Inner window*/ +WINDOW *inwin; +/*Cursor position*/ +int cursorl=LINE-1, cursorc=COL/2, startl, startc; +/*Key number*/ +int ch; +/*Clock*/ +struct timespec ts; +char buff[20]; +void *bracket_thread(void *win) +{ + for(int i=0; i<10; i++) + { + pthread_mutex_lock(&mtx); + wmove(inwin, 1, COL/4); + wattron(inwin, COLOR_PAIR(2)); + wprintw(inwin, "Thread for bracket done!"); + wattroff(inwin, COLOR_PAIR(2)); + wrefresh(inwin); + pthread_mutex_unlock(&mtx); + } +} +void *ball_thread(void *win) +{ + for(int i=0; i<10; i++) + { + pthread_mutex_lock(&mtx); + wmove(inwin, 2, COL/4); + wattron(inwin, COLOR_PAIR(2)); + wprintw(inwin, "Thread for ball done!"); + wattroff(inwin, COLOR_PAIR(2)); + wrefresh(inwin); + pthread_mutex_unlock(&mtx); + } +} +int main(int argc, char *argv[]) +{ + /*Outer window*/ + initscr(); + startl=LINES/2-LINE/2; + startc=COLS/2-COL/2; + /*Color enabled*/ + start_color(); + init_pair(1, COLOR_RED, COLOR_BLACK); + init_pair(2, COLOR_GREEN, COLOR_BLACK); + init_pair(3, COLOR_BLUE, COLOR_BLACK); + /*Cursor hidden*/ + curs_set(0); + /*Inner window set*/ + inwin = newwin(LINE, COL, startl, startc); + /*Multithreading*/ + pthread_mutex_init(&mtx, PTHREAD_MUTEX_NORMAL); + pthread_create(&bracket_th, NULL, bracket_thread, inwin); + pthread_create(&ball_th, NULL, ball_thread, inwin); + /*Timeout enabled for wgetch*/ + wtimeout(inwin, 50); + /*Keypad enabled*/ + keypad(inwin, TRUE); + /*Inner border*/ + box(inwin, '|', '-'); + /*Inner window title*/ + wmove(inwin, 0, COL/4); + wattron(inwin, COLOR_PAIR(2)); + wprintw(inwin, "Push 'q' to quit"); + wmove(inwin, 0, COL-11); + timespec_get(&ts, TIME_UTC); + strftime(buff, sizeof buff, "%H:%M\'%S\"", gmtime(&ts.tv_sec)); + wprintw(inwin, "%s", buff); + wattroff(inwin, COLOR_PAIR(2)); + /*Inner window updated*/ + wrefresh(inwin); + /*Key expected*/ + ch = wgetch(inwin); + /*Inner window cleared before next update*/ + wclear(inwin); + while(ch!=(int)'q') + { + /*Inner border*/ + box(inwin, '|', '-'); + /*Inner window title*/ + wmove(inwin, 0, COL/4); + wattron(inwin, COLOR_PAIR(2)); + wprintw(inwin, "Push 'q' to quit"); + wmove(inwin, 0, COL-11); + timespec_get(&ts, TIME_UTC); + strftime(buff, sizeof buff, "%H:%M\'%S\"", gmtime(&ts.tv_sec)); + wprintw(inwin, "%s", buff); + wattroff(inwin, COLOR_PAIR(2)); + wrefresh(inwin); + ch = wgetch(inwin); + wclear(inwin); + } + endwin(); + pthread_join(bracket_th, NULL); + pthread_join(ball_th, NULL); + pthread_exit(NULL); + return EXIT_SUCCESS; +}