131 lines
3.0 KiB
C
131 lines
3.0 KiB
C
#include "game.h"
|
|
|
|
#define BACKGROUND_COLOR 0x2a0a29
|
|
|
|
//#define SCREEN_STRETCH
|
|
|
|
static uint32_t canvas[H][W];
|
|
|
|
static int last_draw_idx = 0;
|
|
static struct draw_info_t {
|
|
int x, y;
|
|
} last_draw[1000];
|
|
|
|
extern char font8x8_basic[128][8];
|
|
static int x_adjust;
|
|
static int y_adjust;
|
|
|
|
static inline void draw_rect_adjust(uint32_t *pixels, int x, int y, int w, int h) {
|
|
draw_rect(pixels, x + x_adjust, y + y_adjust, w, h);
|
|
}
|
|
|
|
void init_screen(void) {
|
|
for (int y = 0; y < H; y ++)
|
|
for (int x = 0; x < W; x ++)
|
|
canvas[y][x] = BACKGROUND_COLOR;
|
|
|
|
assert(screen_width() >= W);
|
|
assert(screen_height() >= H);
|
|
x_adjust = (screen_width() - W) / 2;
|
|
y_adjust = (screen_height() - H) / 2;
|
|
draw_rect_adjust(&canvas[0][0], 0, 0, W, H);
|
|
draw_sync();
|
|
}
|
|
|
|
char *itoa(int n) {
|
|
static char s[64];
|
|
int i = sizeof(s) - 1;
|
|
do {
|
|
s[--i] = n % 10 + '0';
|
|
n /= 10;
|
|
} while(n > 0);
|
|
return &s[i];
|
|
}
|
|
|
|
static inline void draw_character(char ch, int x, int y, int color) {
|
|
int i, j;
|
|
char *p = font8x8_basic[(int)ch];
|
|
uint32_t buf[8][8];
|
|
for (i = 0; i < 8; i ++)
|
|
for (j = 0; j < 8; j ++) {
|
|
assert(x + j < W && y + i < H);
|
|
if ((p[i] >> j) & 1) {
|
|
canvas[y + i][x + j] = color;
|
|
buf[i][j] = color;
|
|
}
|
|
else {
|
|
buf[i][j] = canvas[y + i][x + j];
|
|
}
|
|
}
|
|
|
|
draw_rect_adjust(&buf[0][0], x, y, 8, 8);
|
|
last_draw[last_draw_idx ++] = (struct draw_info_t){ .x = x, .y = y };
|
|
}
|
|
|
|
static inline void draw_string(const char *str, int x, int y, int color) {
|
|
while (*str) {
|
|
draw_character(*str ++, x, y, color);
|
|
if (x + 8 >= W) {
|
|
y += 8; x = 0;
|
|
} else {
|
|
x += 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void clear_character(int x, int y) {
|
|
int i, j;
|
|
uint32_t buf[8][8];
|
|
for (i = 0; i < 8; i ++)
|
|
for (j = 0; j < 8; j ++) {
|
|
assert(x + j < W && y + i < H);
|
|
canvas[y + i][x + j] = BACKGROUND_COLOR;
|
|
buf[i][j] = BACKGROUND_COLOR;
|
|
}
|
|
|
|
draw_rect_adjust(&buf[0][0], x, y, 8, 8);
|
|
}
|
|
|
|
static void clear_screen() {
|
|
int i;
|
|
for (i = 0; i < last_draw_idx; i ++) {
|
|
clear_character(last_draw[i].x, last_draw[i].y);
|
|
}
|
|
last_draw_idx = 0;
|
|
}
|
|
|
|
void redraw_screen() {
|
|
fly_t it;
|
|
const char *hit, *miss;
|
|
|
|
clear_screen();
|
|
|
|
/* 绘制每个字符 */
|
|
for (it = characters(); it != NULL; it = it->_next) {
|
|
draw_character(it->text + 'A', it->x, it->y, 0xffffffff);
|
|
}
|
|
|
|
/* 绘制命中数、miss数、最后一次按键扫描码和fps */
|
|
const char *key = itoa(last_key_code());
|
|
draw_string(key, 0, H - 8, 0xffffffff);
|
|
hit = itoa(get_hit());
|
|
draw_string(hit, W - strlen(hit) * 8, 0, 0x00ff00);
|
|
miss = itoa(get_miss());
|
|
draw_string(miss, W - strlen(miss) * 8, H - 8, 0xfa5858);
|
|
const char *fps = itoa(get_fps());
|
|
draw_string(fps, 0, 0, 0xf3f781);
|
|
draw_string("FPS", strlen(fps) * 8, 0, 0xf3f781);
|
|
|
|
#ifdef SCREEN_STRETCH
|
|
assert(0);
|
|
int w = screen_width();
|
|
int h = screen_height();
|
|
for (int x = 0; x < w; x ++)
|
|
for (int y = 0; y < h; y ++) {
|
|
draw_rect(&canvas[y * H / h][x * W / w], x, y, 1, 1);
|
|
}
|
|
#endif
|
|
|
|
draw_sync();
|
|
}
|