new typing game

This commit is contained in:
Yanyan Jiang 2020-08-13 12:30:50 +00:00 committed by Zihao Yu
parent 87220d57be
commit 0c534454bd
3 changed files with 106 additions and 49 deletions

View file

@ -1,3 +1,3 @@
NAME = typing-game NAME = typing-game
SRCS = game.c SRCS = game.c font.c
include $(AM_HOME)/Makefile include $(AM_HOME)/Makefile

View file

@ -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,
};

View file

@ -2,17 +2,25 @@
#include <klib.h> #include <klib.h>
#include <klib-macros.h> #include <klib-macros.h>
#define MAXCH 256 #define FPS 30
#define FPS 60 #define CPS 5
#define CHAR_PER_SEC 10 #define CHAR_W 8
#define CHAR_H 16
#define NCHAR 128
#define FG_COL 0xeeeeee
#define BG_COL 0x2a0a29
struct character { struct character {
char ch; char ch;
int x, y, v; int x, y, v, t;
} chars[MAXCH]; } chars[NCHAR];
int screen_width, screen_height, char_width, char_height; int screen_w, screen_h, hit, miss, wrong;
int 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) { int randint(int l, int r) {
return l + (rand() & 0x7fffffff) % (r - l + 1); return l + (rand() & 0x7fffffff) % (r - l + 1);
@ -21,33 +29,60 @@ int randint(int l, int r) {
void new_char() { void new_char() {
for (int i = 0; i < LENGTH(chars); i++) { for (int i = 0; i < LENGTH(chars); i++) {
struct character *c = &chars[i]; struct character *c = &chars[i];
if (c->ch == '\0') { if (!c->ch) {
c->ch = 'A' + randint(0, 25); 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->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; return;
} }
} }
} }
void progress(int frame) { void game_logic_update(int frame) {
if (frame % (FPS / CHAR_PER_SEC) == 0) { if (frame % (FPS / CPS) == 0) new_char();
new_char();
}
for (int i = 0; i < LENGTH(chars); i++) { for (int i = 0; i < LENGTH(chars); i++) {
struct character *c = &chars[i]; struct character *c = &chars[i];
if (c->ch) { if (c->ch) {
if (c->t > 0) {
if (--c->t == 0) {
c->ch = '\0';
}
} else {
c->y += c->v; c->y += c->v;
if (c->y < 0) { if (c->y < 0) {
c->ch = '\0'; c->ch = '\0';
} }
if (c->y + char_height >= screen_height) { if (c->y + CHAR_H >= screen_h) {
miss++; miss++;
c->ch = '\0'; 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) { void check_hit(char ch) {
@ -62,30 +97,30 @@ void check_hit(char ch) {
wrong++; wrong++;
} else { } else {
hit++; 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() { void video_init() {
static int x[MAXCH], y[MAXCH], n; screen_w = io_read(AM_GPU_CONFIG).width;
screen_h = io_read(AM_GPU_CONFIG).height;
for (int i = 0; i < n; i++) { extern char font[];
io_write(AM_GPU_FBDRAW, x[i], y[i], blank, char_width, char_height, false); for (int i = 0; i < CHAR_W * CHAR_H; i++)
blank[i] = BG_COL;
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);
} }
n = 0; for (int ch = 0; ch < 26; ch++) {
for (int i = 0; i < LENGTH(chars); i++) { char *c = &font[CHAR_H * ch];
struct character *c = &chars[i]; for (int i = 0, y = 0; y < CHAR_H; y++)
if (c->ch) { for (int x = 0; x < CHAR_W; x++, i++)
x[n] = c->x; y[n] = c->y; n++; px[ch][i] = ((c[y] >> (CHAR_W - x - 1)) & 1) ? FG_COL : BG_COL;
io_write(AM_GPU_FBDRAW, c->x, c->y, px, char_width, char_height, false);
} }
}
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] = { char lut[256] = {
@ -99,24 +134,18 @@ char lut[256] = {
}; };
int main() { 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(); ioe_init();
video_init();
screen_width = io_read(AM_GPU_CONFIG).width; panic_on(!io_read(AM_TIMER_CONFIG).present, "requires timer");
screen_height = io_read(AM_GPU_CONFIG).height; panic_on(!io_read(AM_INPUT_CONFIG).present, "requires keyboard");
int current = 0, rendered = 0; int current = 0, rendered = 0;
while (1) { while (1) {
int frames = io_read(AM_TIMER_UPTIME).us / (1000000 / FPS); int frames = io_read(AM_TIMER_UPTIME).us / (1000000 / FPS);
while (current < frames) { for (; current < frames; current++) {
progress(current); game_logic_update(current);
current++;
} }
while (1) { while (1) {