6 高速计数器(harib08f)
实验顺利结束了,我们还把图层的高度设置恢复原样,然后再试着做个动作更丰富的窗口。做成什么样呢?我们就做一个能够计数,并将计数结果显示出来的窗口吧。计数器在英语中是counter,所以我们就将窗口的名称改为counter。
我们只改写了10行就得到了下面这个程序。
本次的bootpack.c节选
void HariMain(void)
{
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
char s[40], keybuf[32], mousebuf[128];
int mx, my, i;
unsigned int memtotal, count = 0; /* 这里! */
struct MOUSE_DEC mdec;
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
struct SHTCTL *shtctl;
struct SHEET *sht_back, *sht_mouse, *sht_win;
unsigned char *buf_back, buf_mouse[256], *buf_win;
(中略)
init_palette();
shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);
sht_back = sheet_alloc(shtctl);
sht_mouse = sheet_alloc(shtctl);
sht_win = sheet_alloc(shtctl);
buf_back = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);
buf_win = (unsigned char *) memman_alloc_4k(memman, 160 * 52); /* 这里! */
sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* 没有透明色 */
sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);
sheet_setbuf(sht_win, buf_win, 160, 52, -1); /* 没有透明色 */ /* 这里! */
init_screen8(buf_back, binfo->scrnx, binfo->scrny);
init_mouse_cursor8(buf_mouse, 99);
make_window8(buf_win, 160, 52, "counter"); /* 这里! */
sheet_slide(sht_back, 0, 0);
mx = (binfo->scrnx - 16) / 2; /* 为使其处于画面中央位置,计算坐标 */
my = (binfo->scrny - 28 - 16) / 2;
sheet_slide(sht_mouse, mx, my);
sheet_slide(sht_win, 80, 72);
sheet_updown(sht_back, 0);
sheet_updown(sht_win, 1);
sheet_updown(sht_mouse, 2);
sprintf(s, "(%3d, %3d)", mx, my);
putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s);
sprintf(s, "memory %dMB free : %dKB",
memtotal / (1024 * 1024), memman_total(memman) / 1024);
putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s);
sheet_refresh(sht_back, 0, 0, binfo->scrnx, 48);
for (;;) {
count++; /* 从这里开始 */
sprintf(s, "%010d", count);
boxfill8(buf_win, 160, COL8_C6C6C6, 40, 28, 119, 43);
putfonts8_asc(buf_win, 160, 40, 28, COL8_000000, s);
sheet_refresh(sht_win, 40, 28, 120, 44); /* 到这里结束 */
io_cli();
if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) {
io_sti(); /* 不做HLT */
} else {
(中略)
}
}
}
这次不再采用HLT,因为与其让CPU有空睡觉(HLT命令),还不如让它在电力许可的范围内去全力计数。正因为这个原因,我们的计数器才被称为高速计数器。
按照惯例,我们来“make run”。
计数啦!
运行成功,动作正常,真顺利呀!可是再仔细一看,怎么总觉得显示的内容在闪烁呢(注:在上面截图中看不出来)?这可不行。
为什么会出现这种现象呢?这是由于在刷新的时候,总是先刷新refresh范围内的背景图层,然后再刷新窗口图层,所以肯定就会闪烁了。可是我们使用Windows的时候就没见过这种闪烁,因此肯定有什么好的解决方法。
于是解决这个问题就成了我们下节内容的主题。