From 95785faf5b51aba9e5da25bcb3d633d6d881b0b2 Mon Sep 17 00:00:00 2001 From: girst Date: Fri, 31 Aug 2018 23:42:21 +0200 Subject: [PATCH] refactor pause screen; todos, readme updated --- README.md | 11 ++++++++--- viiper.c | 47 ++++++++++++++++++++++++++++++----------------- viiper.h | 1 + 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index f556b22..26881a3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ TODO: find a better name -## Dependencies +## Requirements You'll need either a terminal emulator with good Unicode (Emoji) support and a compatible fonts, or an actual DEC VT220 to fully enjoy the graphics of this @@ -34,10 +34,16 @@ game. This is what I'd recommend: - TODO decaying points? (more points the faster you get the food) - TODO wall-wrap-around mode? - TODO fix all `grep -n TODO viiper.c` - - TODO VT220 chrsaet based on soft downloadable character set (->minesviiper) + - TODO VT220 charset based on soft downloadable character set (->minesviiper) ## Notes +### Why this program is using SIGALRM instead of multithreading + +One of the main reasons for making this game was to try some unconventional +programming ideas I had. Seeing how far I can get with only a single thread was +one of them. Some others were pure lazyness, though. + ### terminal compat to display emojis, we need a terminal that can handle a color emoji font (no @@ -52,7 +58,6 @@ for KDE's konsole you'll need [this fontconfig](https://gist.github.com/IgnoredAmbience/7c99b6cf9a8b73c9312a71d1209d9bbb) and follow the steps inside. - ### strange behaviour of SIGALRM I'm using SIGALRM to advance the snake's position. during some refactoring I diff --git a/viiper.c b/viiper.c index dd3f878..fcfb9c8 100644 --- a/viiper.c +++ b/viiper.c @@ -57,10 +57,10 @@ struct game { int w; /* field width */ int h; /* field height */ int d; /* direction the snake is looking */ - int t; /* time of game start */ int p; /* score */ - int b; /* time of next bonus item spawn */ float v; /* velocity in moves per second */ + time_t t; /* time of game start */ + time_t b; /* time of next bonus item spawn */ struct snake* s; /* snek */ struct item* i; /* items (food, boni) */ struct directions { @@ -175,18 +175,11 @@ int viiper(void) { for(;;) { switch (getctrlseq()) { - case CTRSEQ_CURSOR_LEFT: case 'h':append_movement(WEST); break; - case CTRSEQ_CURSOR_DOWN: case 'j':append_movement(SOUTH); break; - case CTRSEQ_CURSOR_UP: case 'k':append_movement(NORTH); break; - case CTRSEQ_CURSOR_RIGHT:case 'l':append_movement(EAST); break; - case 'p': //TODO: causes bonus items to be spawned too early; have to increase all timers - timer_setup(0); - move_ph (g.h/2+LINE_OFFSET, g.w*CW/2); - printf ("\033[5mPAUSE\033[0m"); /* blinking text */ - if (getchar() == 'q') exit(0); - show_playfield(); - timer_setup(1); - break; + case 'h': case CTRSEQ_CURSOR_LEFT: append_movement(WEST); break; + case 'j': case CTRSEQ_CURSOR_DOWN: append_movement(SOUTH);break; + case 'k': case CTRSEQ_CURSOR_UP: append_movement(NORTH);break; + case 'l': case CTRSEQ_CURSOR_RIGHT:append_movement(EAST); break; + case 'p': pause_game(); break; case 'r': siglongjmp(game_over, GAME_START); case 'q': siglongjmp(game_over, GAME_EXIT); case CTRL_'L': @@ -336,7 +329,7 @@ void spawn_bonus(void) { } if (g.b < time(NULL)) { /* time to spawn item: */ spawn_item(BONUS, rand() % NUM_BONI, NULL); - g.b = time(NULL) + BONUS_INTERVAL; + g.b = time(NULL) + BONUS_INTERVAL; //TODO: only start counting after old bonus was removed/eaten } } @@ -409,6 +402,26 @@ void draw_sprites (int erase_r, int erase_c) { printf ("%s %0*d %s", BORDER(S,L), score_width, g.p, BORDER(S,R)); } +void pause_game (void) { + time_t pause_start = time(NULL); + time_t pause_diff; + timer_setup(0); + + move_ph (g.h/2+LINE_OFFSET, g.w*CW/2); + printf ("\033[5;7m PAUSE \033[0m"); /* blinking reverse text */ + if (getchar() == 'q') + siglongjmp(game_over, GAME_EXIT); + + /* update all timers, so bonus items don't get out of sync: */ + pause_diff = time(NULL) - pause_start; + g.b += pause_diff; + for (struct item* i = g.i; i; i = i->next) + i->s += pause_diff; + + show_playfield(); + timer_setup(1); +} + #define MOVE_POPUP(WIDTH, LINE) \ move_ph(g.h/2+LINE_OFFSET-1+LINE,(g.w*op.sch->display_width-WIDTH)/2) //TODO: macro does not correctly centre in DEC mode @@ -422,7 +435,7 @@ int end_screen(char* message) { MOVE_POPUP(msg_w, 0); printf("%s %s %s", BORDER(C,L), message, BORDER(C,R)); MOVE_POPUP(msg_w, 1); - //TODO: requires shifting into ASCII/multilingual charset in DEC mode + //TODO: requires shifting into ASCII/multilingual charset in DEC mode -- put graphics into upper/right charset? printf("%s `r' restart%*s%s", BORDER(C,L), msg_w-10, "", BORDER(C,R)); MOVE_POPUP(msg_w, 2); printf("%s `q' quit%*s%s", BORDER(C,L), msg_w-7, "", BORDER(C,R)); @@ -613,7 +626,7 @@ void signal_handler (int signum) { switch (signum) { case SIGALRM: snake_advance(); - spawn_bonus(); + spawn_bonus(); //TODO: currently, a bonus is spawned every x secs. should be x secs after last bonus disappeared. break; case SIGINT: exit(128+SIGINT); diff --git a/viiper.h b/viiper.h index 98a7765..bbdbfa7 100644 --- a/viiper.h +++ b/viiper.h @@ -70,6 +70,7 @@ void spawn_item (int type, int value, struct item* p_item); void consume_item (struct item* i); void show_playfield (void); void draw_sprites (int erase_r, int erase_c); +void pause_game (void); int end_screen(char* message); void snake_append (struct snake** s, int row, int col); void remove_bonus (struct item* i); -- 2.39.3