向上舍入
假设以0x1000字节为单位,做最简单的向下舍入,我们可以用i = i & 0xfffff000,那么向上舍入就是i = ( i & 0xfffff000) + 0x1000咯!当然不是!还要判断后几位是否为0,如果本来就是0则什么都不做。纠正代码如下:
if((i & 0xfff)!=0){ i= ( i & 0xfffff000) + 0x1000;}
其实还可以再改进一下的,类似于四舍五入的写法i=int(i+0.5),我们可以加上一个0xfff再向下舍入:
i = ( i + 0xfff) & 0xfffff000;
有了它,之前我们写的内存管理函数就清爽多了!!
画面叠加处理
之前我们做了很久内存管理的探讨(很压抑吧),为了转换心情,现在我们尝试解决画面叠加处理的问题吧。
画面的叠加显示,类似于将绘制了图案的透明图层叠加在一起。
结构体定义如下:
/* sheet.c */
#define MAX_SHEETS 256
struct SHEET {
unsigned char *buf;
int bxsize, bysize, vx0, vy0, col_inv, height, flags;
};
struct SHTCTL {
unsigned char *vram;
int xsize, ysize, top;
struct SHEET *sheets[MAX_SHEETS];
struct SHEET sheets0[MAX_SHEETS];
};
在SHEET结构体中需要指明的是,
buf用来记录图层上所描画内容的地址,
bxsize*bysize 表示图层整体大小,
vx0和vy0是表示图层在画面上位置的坐标,
col_inv表示透明色色号(color_invisible),
height表示图层高度,
FLags存放有关图层的各种设定信息。
SHTCTL结构体全称是sheet control,意为图层管理,设置最大图层数为256.
vram,xsize,ysize代表VRAM的地址和画面大小,
top代表最上面图层的高度,
sheets0这个结构体用于存放我们准备的256个图层信息,
sheets用于记忆地址变量的领域,sheets0的图层顺序是混乱的,我们要将排列好的地址写入sheets中。
接下来我们算一下数据存储需要的空间,vram,xsize,ysize,top 他们是4x4字节=16字节,sheets存的是地址所以是256x4字节=1024字节,sheet0存的是结构体,256x32字节=8192字节,总共9232字节。这里我们就需要合理分配内存空间了,这也是为什么之前要先花很长时间来写内存管理的代码。
优化叠加处理
1.鼠标指针只有16x16=256个像素,但在之前的设计中,我们却每次都对整个画面进行刷新,而实际上只要重绘移动前后两个区域,即256x2=512个像素就够了。
2.即使刷新一部分,也要对所有图层的全部像素执行条件语句,判断是否写入,而对于刷新范围以外的部分,完全没必要刷新。既然如此,我们最初就应该把for语句的范围限定在刷新范围之内。
3.值得注意的是,需要处理刷新范围在当前图层外侧的情况。如下图,这个时候我们只需要描绘与鼠标图层重叠的那一小块范围。
但是呢,这还没有考虑到鼠标跑到外边缘的情况。不过还是先休息一下吧!留下一个小BUG,便于下次更快进入状态。(笑)