6 高速计数器(harib08f)

实验顺利结束了,我们还把图层的高度设置恢复原样,然后再试着做个动作更丰富的窗口。做成什么样呢?我们就做一个能够计数,并将计数结果显示出来的窗口吧。计数器在英语中是counter,所以我们就将窗口的名称改为counter。

我们只改写了10行就得到了下面这个程序。

本次的bootpack.c节选

  1. void HariMain(void)
  2. {
  3. struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
  4. char s[40], keybuf[32], mousebuf[128];
  5. int mx, my, i;
  6. unsigned int memtotal, count = 0; /* 这里! */
  7. struct MOUSE_DEC mdec;
  8. struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
  9. struct SHTCTL *shtctl;
  10. struct SHEET *sht_back, *sht_mouse, *sht_win;
  11. unsigned char *buf_back, buf_mouse[256], *buf_win;
  12. (中略)
  13. init_palette();
  14. shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);
  15. sht_back = sheet_alloc(shtctl);
  16. sht_mouse = sheet_alloc(shtctl);
  17. sht_win = sheet_alloc(shtctl);
  18. buf_back = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);
  19. buf_win = (unsigned char *) memman_alloc_4k(memman, 160 * 52); /* 这里! */
  20. sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* 没有透明色 */
  21. sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);
  22. sheet_setbuf(sht_win, buf_win, 160, 52, -1); /* 没有透明色 */ /* 这里! */
  23. init_screen8(buf_back, binfo->scrnx, binfo->scrny);
  24. init_mouse_cursor8(buf_mouse, 99);
  25. make_window8(buf_win, 160, 52, "counter"); /* 这里! */
  26. sheet_slide(sht_back, 0, 0);
  27. mx = (binfo->scrnx - 16) / 2; /* 为使其处于画面中央位置,计算坐标 */
  28. my = (binfo->scrny - 28 - 16) / 2;
  29. sheet_slide(sht_mouse, mx, my);
  30. sheet_slide(sht_win, 80, 72);
  31. sheet_updown(sht_back, 0);
  32. sheet_updown(sht_win, 1);
  33. sheet_updown(sht_mouse, 2);
  34. sprintf(s, "(%3d, %3d)", mx, my);
  35. putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s);
  36. sprintf(s, "memory %dMB free : %dKB",
  37. memtotal / (1024 * 1024), memman_total(memman) / 1024);
  38. putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s);
  39. sheet_refresh(sht_back, 0, 0, binfo->scrnx, 48);
  40. for (;;) {
  41. count++; /* 从这里开始 */
  42. sprintf(s, "%010d", count);
  43. boxfill8(buf_win, 160, COL8_C6C6C6, 40, 28, 119, 43);
  44. putfonts8_asc(buf_win, 160, 40, 28, COL8_000000, s);
  45. sheet_refresh(sht_win, 40, 28, 120, 44); /* 到这里结束 */
  46. io_cli();
  47. if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) {
  48. io_sti(); /* 不做HLT */
  49. } else {
  50. (中略)
  51. }
  52. }
  53. }

这次不再采用HLT,因为与其让CPU有空睡觉(HLT命令),还不如让它在电力许可的范围内去全力计数。正因为这个原因,我们的计数器才被称为高速计数器。

按照惯例,我们来“make run”。

6 高速计数器(harib08f) - 图1

计数啦!

运行成功,动作正常,真顺利呀!可是再仔细一看,怎么总觉得显示的内容在闪烁呢(注:在上面截图中看不出来)?这可不行。

为什么会出现这种现象呢?这是由于在刷新的时候,总是先刷新refresh范围内的背景图层,然后再刷新窗口图层,所以肯定就会闪烁了。可是我们使用Windows的时候就没见过这种闪烁,因此肯定有什么好的解决方法。

于是解决这个问题就成了我们下节内容的主题。