From 0c534454bd8b93a855cc685690c8aa5d144769a9 Mon Sep 17 00:00:00 2001 From: Yanyan Jiang Date: Thu, 13 Aug 2020 12:30:50 +0000 Subject: [PATCH] new typing game --- kernels/typing-game/Makefile | 2 +- kernels/typing-game/font.c | 28 ++++++++ kernels/typing-game/game.c | 125 +++++++++++++++++++++-------------- 3 files changed, 106 insertions(+), 49 deletions(-) create mode 100644 kernels/typing-game/font.c diff --git a/kernels/typing-game/Makefile b/kernels/typing-game/Makefile index 27cbbd9..58717ba 100644 --- a/kernels/typing-game/Makefile +++ b/kernels/typing-game/Makefile @@ -1,3 +1,3 @@ NAME = typing-game -SRCS = game.c +SRCS = game.c font.c include $(AM_HOME)/Makefile diff --git a/kernels/typing-game/font.c b/kernels/typing-game/font.c new file mode 100644 index 0000000..07f5194 --- /dev/null +++ b/kernels/typing-game/font.c @@ -0,0 +1,28 @@ +char font[] = { + 0x00, 0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x63, 0x63, 0x63, 0x7e, 0x63, 0x63, 0x63, 0x63, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x33, 0x61, 0x60, 0x60, 0x60, 0x60, 0x61, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0x66, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x60, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x7f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x60, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x33, 0x63, 0x60, 0x60, 0x67, 0x63, 0x63, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x77, 0x7f, 0x6b, 0x6b, 0x63, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x63, 0x73, 0x6b, 0x67, 0x63, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x63, 0x63, 0x63, 0x63, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7b, 0x6f, 0x3e, 0x06, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x63, 0x63, 0x63, 0x7e, 0x6c, 0x66, 0x66, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x63, 0x63, 0x30, 0x18, 0x0c, 0x06, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x6b, 0x6b, 0x7f, 0x77, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x63, 0x22, 0x36, 0x1c, 0x1c, 0x36, 0x22, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x03, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x60, 0x7f, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/kernels/typing-game/game.c b/kernels/typing-game/game.c index 1e38620..b611b01 100644 --- a/kernels/typing-game/game.c +++ b/kernels/typing-game/game.c @@ -2,17 +2,25 @@ #include #include -#define MAXCH 256 -#define FPS 60 -#define CHAR_PER_SEC 10 +#define FPS 30 +#define CPS 5 +#define CHAR_W 8 +#define CHAR_H 16 +#define NCHAR 128 +#define FG_COL 0xeeeeee +#define BG_COL 0x2a0a29 struct character { char ch; - int x, y, v; -} chars[MAXCH]; + int x, y, v, t; +} chars[NCHAR]; -int screen_width, screen_height, char_width, char_height; -int hit, miss, wrong; +int screen_w, screen_h, hit, miss, wrong; +uint32_t px[26][CHAR_W * CHAR_H], blank[CHAR_W * CHAR_H]; + +int min(int a, int b) { + return (a < b) ? a : b; +} int randint(int l, int r) { return l + (rand() & 0x7fffffff) % (r - l + 1); @@ -21,35 +29,62 @@ int randint(int l, int r) { void new_char() { for (int i = 0; i < LENGTH(chars); i++) { struct character *c = &chars[i]; - if (c->ch == '\0') { + if (!c->ch) { c->ch = 'A' + randint(0, 25); - c->x = randint(0, screen_width - char_width); + c->x = randint(0, screen_w - CHAR_W); c->y = 0; - c->v = (screen_height - char_height + 1) / randint(FPS * 3 / 2, FPS * 2); + c->v = (screen_h - CHAR_H + 1) / randint(FPS * 3 / 2, FPS * 2); + c->t = 0; return; } } } -void progress(int frame) { - if (frame % (FPS / CHAR_PER_SEC) == 0) { - new_char(); - } +void game_logic_update(int frame) { + if (frame % (FPS / CPS) == 0) new_char(); for (int i = 0; i < LENGTH(chars); i++) { struct character *c = &chars[i]; if (c->ch) { - c->y += c->v; - if (c->y < 0) { - c->ch = '\0'; - } - if (c->y + char_height >= screen_height) { - miss++; - c->ch = '\0'; + if (c->t > 0) { + if (--c->t == 0) { + c->ch = '\0'; + } + } else { + c->y += c->v; + if (c->y < 0) { + c->ch = '\0'; + } + if (c->y + CHAR_H >= screen_h) { + miss++; + c->v = 0; + c->y = screen_h - CHAR_H; + c->t = FPS; + } } } } } +void render() { + static int x[NCHAR], y[NCHAR], n = 0; + + for (int i = 0; i < n; i++) { + io_write(AM_GPU_FBDRAW, x[i], y[i], blank, CHAR_W, CHAR_H, false); + } + + n = 0; + for (int i = 0; i < LENGTH(chars); i++) { + struct character *c = &chars[i]; + if (c->ch) { + x[n] = c->x; y[n] = c->y; n++; + io_write(AM_GPU_FBDRAW, c->x, c->y, px[c->ch - 'A'], CHAR_W, CHAR_H, false); + } + } + io_write(AM_GPU_FBDRAW, 0, 0, NULL, 0, 0, true); + for (int i = 0; i < 40; i++) putch('\b'); + printf("Hit: %d; Miss: %d; Wrong: %d", hit, miss, wrong); +} + void check_hit(char ch) { int m = -1; for (int i = 0; i < LENGTH(chars); i++) { @@ -62,30 +97,30 @@ void check_hit(char ch) { wrong++; } else { hit++; - chars[m].v = -(screen_height - char_height + 1) / (FPS); + chars[m].v = -(screen_h - CHAR_H + 1) / (FPS); } } -uint32_t px[32 * 16], blank[32 * 16]; -void render() { - static int x[MAXCH], y[MAXCH], n; +void video_init() { + screen_w = io_read(AM_GPU_CONFIG).width; + screen_h = io_read(AM_GPU_CONFIG).height; - for (int i = 0; i < n; i++) { - io_write(AM_GPU_FBDRAW, x[i], y[i], blank, char_width, char_height, false); - } + extern char font[]; + for (int i = 0; i < CHAR_W * CHAR_H; i++) + blank[i] = BG_COL; - n = 0; - for (int i = 0; i < LENGTH(chars); i++) { - struct character *c = &chars[i]; - if (c->ch) { - x[n] = c->x; y[n] = c->y; n++; - io_write(AM_GPU_FBDRAW, c->x, c->y, px, char_width, char_height, false); + for (int x = 0; x < screen_w; x += CHAR_W) + for (int y = 0; y < screen_h; y += CHAR_H) { + io_write(AM_GPU_FBDRAW, x, y, blank, min(CHAR_W, screen_w - x), min(CHAR_H, screen_h - y), false); } + + for (int ch = 0; ch < 26; ch++) { + char *c = &font[CHAR_H * ch]; + for (int i = 0, y = 0; y < CHAR_H; y++) + for (int x = 0; x < CHAR_W; x++, i++) + px[ch][i] = ((c[y] >> (CHAR_W - x - 1)) & 1) ? FG_COL : BG_COL; } - io_write(AM_GPU_FBDRAW, 0, 0, NULL, 0, 0, true); - for (int i = 0; i < 80; i++) putch('\b'); - printf("Hit: %d; Miss: %d; Wrong: %d", hit, miss, wrong); } char lut[256] = { @@ -99,24 +134,18 @@ char lut[256] = { }; int main() { - char_width = 8; - char_height = 16; - - for (int i = 0; i < char_width * char_height; i ++) px[i] = 0x345678; - for (int i = 0; i < char_width * char_height; i ++) blank[i] = 0; - ioe_init(); + video_init(); - screen_width = io_read(AM_GPU_CONFIG).width; - screen_height = io_read(AM_GPU_CONFIG).height; + panic_on(!io_read(AM_TIMER_CONFIG).present, "requires timer"); + panic_on(!io_read(AM_INPUT_CONFIG).present, "requires keyboard"); int current = 0, rendered = 0; while (1) { int frames = io_read(AM_TIMER_UPTIME).us / (1000000 / FPS); - while (current < frames) { - progress(current); - current++; + for (; current < frames; current++) { + game_logic_update(current); } while (1) {