diff --git a/share/examples/gpanel/flappy.c b/share/examples/gpanel/flappy.c index c5f52db..a05a2f1 100644 --- a/share/examples/gpanel/flappy.c +++ b/share/examples/gpanel/flappy.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #ifdef CROSS @@ -25,7 +26,12 @@ /* * Redraw every 50 msec */ -#define DRAW_LOOP_INTERVAL 50 +#define DRAW_LOOP_INTERVAL 50 + +/* + * File name for saving the high score. + */ +#define SCORE_FILENAME "flappy.score" /* * Data from external font files. @@ -34,14 +40,14 @@ extern const struct gpanel_font_t font_lucidasans15; extern const struct gpanel_font_t font_lucidasans28; int wing; -int fx, fy, fallRate; -int pillarPos, gapPos; +int fx, fy, fall_rate; +int pillar_pos, gap_pos; int score; -int highScore = 0; +int high_score = 0; int running = 0; int crashed = 0; -int scrPress = 0; -time_t nextDrawLoopRunTime; +int scr_press = 0; +time_t next_draw_time; void rect(int color, int x, int y, int w, int h) { @@ -53,7 +59,7 @@ void fill(int color, int x, int y, int w, int h) gpanel_fill(color, x, y, x+w-1, y+h-1); } -void drawPillar(int x, int gap) +void draw_pillar(int x, int gap) { if (x >= 320) return; @@ -67,25 +73,25 @@ void drawPillar(int x, int gap) rect(BLACK, x+1, gap+91, 48, 138-gap); } -void clearPillar(int x, int gap) +void clear_pillar(int x, int gap) { if (x >= 320) return; - // "cheat" slightly and just clear the right hand pixels - // to help minimise flicker, the rest will be overdrawn + /* "Cheat" slightly and just clear the right hand pixels + * to help minimise flicker, the rest will be overdrawn. */ fill(BLUE, x+45, 0, 5, gap); fill(BLUE, x+45, gap+90, 5, 140-gap); } -void clearFlappy(int x, int y) +void clear_flappy(int x, int y) { fill(BLUE, x, y, 34, 24); } -void drawFlappy(int x, int y) +void draw_flappy(int x, int y) { - // Upper & lower body + /* Upper & lower body */ fill(BLACK, x+2, y+8, 2, 10); fill(BLACK, x+4, y+6, 2, 2); fill(BLACK, x+6, y+4, 2, 2); @@ -98,7 +104,7 @@ void drawFlappy(int x, int y) fill(BLACK, x+4, y+18, 2, 2); fill(BLACK, x+6, y+20, 4, 2); - // Body fill + /* Body fill */ fill(YELLOW, x+12, y+2, 6, 2); fill(YELLOW, x+8, y+4, 8, 2); fill(YELLOW, x+6, y+6, 10, 2); @@ -110,7 +116,7 @@ void drawFlappy(int x, int y) fill(YELLOW, x+6, y+18, 12, 2); fill(YELLOW, x+10, y+20, 10, 2); - // Eye + /* Eye */ fill(BLACK, x+18, y+2, 2, 2); fill(BLACK, x+16, y+4, 2, 6); fill(BLACK, x+18, y+10, 2, 2); @@ -120,7 +126,7 @@ void drawFlappy(int x, int y) fill(WHITE, x+26, y+6, 2, 6); fill(BLACK, x+24, y+6, 2, 4); - // Beak + /* Beak */ fill(BLACK, x+20, y+12, 12, 2); fill(BLACK, x+18, y+14, 2, 2); fill(RED, x+20, y+14, 12, 2); @@ -134,8 +140,10 @@ void drawFlappy(int x, int y) fill(BLACK, x+20, y+20, 10, 2); } -// Wing down -void drawWing1(int x, int y) +/* + * Wing down. + */ +void draw_wing1(int x, int y) { fill(BLACK, x, y+14, 2, 6); fill(BLACK, x+2, y+20, 8, 2); @@ -147,8 +155,10 @@ void drawWing1(int x, int y) fill(WHITE, x+10, y+14, 2, 2); } -// Wing middle -void drawWing2(int x, int y) +/* + * Wing middle. + */ +void draw_wing2(int x, int y) { fill(BLACK, x+2, y+10, 10, 2); fill(BLACK, x+2, y+16, 10, 2); @@ -157,8 +167,10 @@ void drawWing2(int x, int y) fill(WHITE, x+2, y+12, 10, 4); } -// Wing up -void drawWing3(int x, int y) +/* + * Wing up. + */ +void draw_wing3(int x, int y) { fill(BLACK, x+2, y+6, 8, 2); fill(BLACK, x, y+8, 2, 6); @@ -180,13 +192,13 @@ time_t millis() return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); } -void startGame() +void start_game() { fx = 50; fy = 125; - fallRate = -1; - pillarPos = 320; - gapPos = 60; + fall_rate = -1; + pillar_pos = 320; + gap_pos = 60; crashed = 0; score = 0; @@ -196,14 +208,11 @@ void startGame() gpanel_text(&font_lucidasans15, WHITE, BLUE, 50, 180, "(Press Space to start)"); - //TODO: read high score value from file. - highScore = 0; + char score_line[80]; + sprintf(score_line, "High Score: %u", high_score); + gpanel_text(&font_lucidasans28, GREEN, BLUE, 10, 60, score_line); - char scoreLine[80]; - sprintf(scoreLine, "High Score: %u", highScore); - gpanel_text(&font_lucidasans28, GREEN, BLUE, 10, 60, scoreLine); - - // Draw Ground + /* Draw ground. */ int tx, ty = 230; for (tx = 0; tx <= 300; tx += 20) { gpanel_fill_triangle(GREEN, tx, ty, tx+9, ty, tx, ty+9); @@ -212,45 +221,45 @@ void startGame() gpanel_fill_triangle(GREEN, tx+19, ty+9, tx+19, ty, tx+10, ty+9); } - nextDrawLoopRunTime = millis() + DRAW_LOOP_INTERVAL; + next_draw_time = millis() + DRAW_LOOP_INTERVAL; } -void drawLoop() +void draw_loop() { - // clear moving items - clearPillar(pillarPos, gapPos); - clearFlappy(fx, fy); + /* Clear moving items. */ + clear_pillar(pillar_pos, gap_pos); + clear_flappy(fx, fy); - // move items + /* Move items. */ if (running) { - fy += fallRate; - fallRate++; + fy += fall_rate; + fall_rate++; - pillarPos -= 5; - if (pillarPos == 0) { + pillar_pos -= 5; + if (pillar_pos == 0) { score++; } - else if (pillarPos < -50) { - pillarPos = 320; - gapPos = 20 + random() % 100; + else if (pillar_pos < -50) { + pillar_pos = 320; + gap_pos = 20 + random() % 100; } } - // draw moving items & animate - drawPillar(pillarPos, gapPos); - drawFlappy(fx, fy); + /* Draw moving items & animate. */ + draw_pillar(pillar_pos, gap_pos); + draw_flappy(fx, fy); switch (wing) { case 0: case 1: - drawWing1(fx, fy); + draw_wing1(fx, fy); break; case 2: case 3: - drawWing2(fx, fy); + draw_wing2(fx, fy); break; case 4: case 5: - drawWing3(fx, fy); + draw_wing3(fx, fy); break; } wing++; @@ -258,35 +267,77 @@ void drawLoop() wing = 0; } -void checkCollision() +/* + * Write high score value to file. + */ +void save_score() { - // Collision with ground + int fd, nbytes; + char line[80]; + + fd = open(SCORE_FILENAME, O_WRONLY | O_CREAT, 0644); + if (fd < 0) { + perror(SCORE_FILENAME); + return; + } + sprintf(line, "%u\n", high_score); + nbytes = strlen(line); + if (write(fd, line, nbytes) != nbytes) + perror(SCORE_FILENAME); + close(fd); +} + +/* + * Read high score value from file. + */ +void load_score() +{ + int fd, nbytes; + char line[80]; + + fd = open(SCORE_FILENAME, O_RDONLY); + if (fd < 0) { + /* No high score file yet. */ + return; + } + nbytes = read(fd, line, sizeof(line)); + if (nbytes <= 0) { + if (nbytes < 0) + perror(SCORE_FILENAME); + return; + } + close(fd); + high_score = strtol(line, 0, 0); +} + +void check_collision() +{ + /* Collision with ground. */ if (fy > 206) crashed = 1; - // Collision with pillar - if (fx + 34 > pillarPos && fx < pillarPos + 50) - if (fy < gapPos || fy + 24 > gapPos + 90) + /* Collision with pillar. */ + if (fx + 34 > pillar_pos && fx < pillar_pos + 50) + if (fy < gap_pos || fy + 24 > gap_pos + 90) crashed = 1; if (crashed) { gpanel_text(&font_lucidasans28, RED, BLUE, 50, 50, "Game Over!"); - char scoreLine[80]; - sprintf(scoreLine, "Score: %u", score); - gpanel_text(&font_lucidasans28, RED, BLUE, 50, 100, scoreLine); + char score_line[80]; + sprintf(score_line, "Score: %u", score); + gpanel_text(&font_lucidasans28, RED, BLUE, 50, 100, score_line); - if (score > highScore) { - highScore = score; + if (score > high_score) { + high_score = score; gpanel_text(&font_lucidasans28, RED, BLUE, 50, 150, "NEW HIGH!"); - - //TODO: Write high score value to file. + save_score(); } - // stop animation + /* Stop animation. */ running = 0; - // delay to stop any last minute clicks from restarting immediately + /* Delay to stop any last minute clicks from restarting immediately. */ sleep(1); } } @@ -314,7 +365,7 @@ int get_input() ioctl(0, TIOCGETP, &origtty); newtty = origtty; - newtty.sg_flags &= ~(ECHO|CRMOD|XTABS); + newtty.sg_flags &= ~(ECHO|XTABS); newtty.sg_flags |= CBREAK; ioctl(0, TIOCSETP, &newtty); } @@ -334,45 +385,46 @@ int main() char *devname = "/dev/tft0"; int xsize = 320, ysize = 240; + signal(SIGINT, quit); if (gpanel_open(devname) < 0) { printf("Cannot open %s\n", devname); exit(-1); } gpanel_clear(BLUE, &xsize, &ysize); - startGame(); - signal(SIGINT, quit); + load_score(); + start_game(); for (;;) { - if (millis() > nextDrawLoopRunTime && !crashed) { - drawLoop(); - checkCollision(); - nextDrawLoopRunTime += DRAW_LOOP_INTERVAL; + if (millis() > next_draw_time && !crashed) { + draw_loop(); + check_collision(); + next_draw_time += DRAW_LOOP_INTERVAL; } usleep(10000); - // Get user input. + /* Get user input. */ int user_input = get_input(); - // Process "user input" - if (user_input > 0 && !scrPress) { + /* Process "user input". */ + if (user_input > 0 && !scr_press) { if (crashed) { - // restart game - startGame(); + /* Restart game. */ + start_game(); } else if (!running) { - // clear text & start scrolling + /* Clear text & start scrolling. */ gpanel_fill(BLUE, 0, 0, 320-1, 100); gpanel_fill(BLUE, 0, 180, 320-1, 205); running = 1; } else { - // fly up - fallRate = -8; - scrPress = 1; + /* Fly up. */ + fall_rate = -8; + scr_press = 1; } - } else if (user_input == 0 && scrPress) { - // Attempt to throttle presses - scrPress = 0; + } else if (user_input == 0 && scr_press) { + /* Attempt to throttle presses. */ + scr_press = 0; } } }