1 鼠标显示问题(harib08a)
第一小节解决了鼠标的一点细节问题:可以向右或向下移动到画面之外隐藏起来。
当前不能这么做的原因:
代码很简单,当鼠标移出屏幕时会被修改成 binfo->scrnx - 16,也就是屏幕边缘。
这里先做一个简单的修改:
make run运行一下:
↑出现图层问题
2 实现画面外的支持(harib08b)
怎样才能让图层位于画面以外时也不出问题呢?因为只有 sheet_refershsub函数在做把图层内容写入VRAM的工作,所以需要对该函数进行优化。
对比图:(修改前 >>>> 修改后:阴影部分为修改后添加的内容)↓
make run运行,现在运行就没有任何问题了。
3 shtctl的指定省略(harib08c)
这一部分作者对函数参数进行了修改。
作者对sheet_updown函数不太满意,因为仅是上下移动图层,就必须指定ctl,太麻烦。
想要改善这个问题,首先需要在 struct SHEET 中加入 *struct SHTCTL ctl。
别想复杂了,只是在结构体中加了一个属性,将两个参数合为了一个。
然后对 shtctl_init也进行追加。
还有 sheet_updown 也需要修改。
4 显示窗口(harib08d)
我们现在做出来的图层框架,已经完全可以完成窗口的叠加处理了,所以这一节做了一个小窗口。
其实方法很简单,就像前面制作背景和鼠标那样,只要先准备一张图层,然后在图层缓冲区内描绘一个貌似窗口的图就可以了。这里制作了一个函数make_window8:
其实这里只是对 graph.c 的 init_screen8 函数稍微进行了改造,而 x 按钮的功能则是通过修改 init_mouse_cursor8 而得到的。
HariMain里也添加了一些内容:
运行一下:
5 小实验(harib08e)*
这一节做了一个小实验,HariMain中有设置图层高度的地方,如果像下面这样,把窗口图层放到最上面,光标图层放在其次,会变成什么样呢?
make run试试看:
可以看到鼠标被窗口覆盖住了。
6 高速计数器(harib08f)
实验顺利结束,把图层的高度恢复成原样,然后再试着做个动作更丰富的窗口,做成什么样呢,我们就做一个能够计数,并将计数结果显示出来的窗口吧。计数器在英语中是 counter,所以我们就将窗口的名称设置为 counter。
这里只改写了10行代码就得到了这个程序。
make run 运行效果:
运行没有问题,窗口成功计数,不过显示的内容在闪烁,这可不行。
为什么会出现这种现象呢?这是由于在刷新的时候,总是先刷新 refresh 范围内的背景图层,然后再刷新窗口图层,所以肯定会闪烁了。
7 消除闪烁(1)(harib08g)
窗口图层刷新是因为窗口的内容有变化,所以要在画面上显示变化后的新内容。基本上来讲,可以认为其他图层的内容没有变化(如果其他图层的内容也变了,那么应该会随后执行该图层的刷新)。
既然如此,图层内容没有变化也进行刷新的话就太浪费了。如果只是窗口变了,那背景就不用刷新了。另外,假如上面有鼠标,但鼠标的图层没有变化,那我们应该刷新吗?必须要刷新。窗口的刷新,可能会覆盖鼠标的一部分显示区域。
综上所述,仅对 refresh 对象及其以上的图层进行刷新就可以了。按照这个思路修改程序。
修改的内容很少,对于 sheet_refresh函数,按照刚才的思路让它只刷新指定的图层和它上面的图层。
在 sheet_slide 函数里,图层的移动有时会导致下面的图层露出,所以要从最下面开始刷新。另一方面,在移动目标处,比新移来的图层位置还要低的图层没什么变化,而且只是隐藏起来了,所以只要刷新移动的图层和它上面的图层就可以了。
在 sheet_updown 函数里,按照同样的思路,针对个别不需要自下而上全部刷新的部分只进行局部刷新。
运行一下:
鼠标一闪一闪的,数字部分的背景闪烁是解决了,可是把鼠标放在上面的时候,鼠标又闪烁起来了。
8 消除闪烁(2)(harib08h)
怎么样才能让鼠标不再闪烁呢?闪烁现象是由于一会儿描绘一会儿消除造成的。所以说要想消除闪烁,就要在刷新窗口时避开鼠标所在的地方对VRAM进行写入处理。这好像挺难的,但是无论如何我们还是要努力一下。
而且如果这里做好了,刷新窗口时就不需要重绘鼠标了,这样速度也能相应提高。
这里的map与算法求解问题中哈希集合进行去除重复非常相似。47
运行一下:
成功解决了鼠标闪烁的问题。
感受
今天的内容还有待继续理解,新增的这些函数参数仅仅是明白了是干啥用的,但是具体的代码实现没有吃透。继续加油