30天自制操作系统(10)
DAY10_叠加处理
1.内存管理(续)
- memory.c中增加了“向上舍入”的部分,即我们要编写一些总是以0x1000字节为单位进行内存分配和释放的函数,它们会把指定的内存大小按0x1000字节为单位向上舍入( roundup)。
- 从向下舍入开始
要想把十六进制的某一位设置为0,同样只进行“与运算”就可以。 - 向上舍入:先向下舍入,再在它的结果上做个加法运算就可以了。(要先判断后几位是不是0)
- 更好的向上舍入的方法:i = (i + 0xfff) & 0xfffff000;
2.叠加处理
- 寻找一种方法,不仅适用于鼠标的叠加,还适用于窗口的叠加。
- 在程序中创建管理多重图层信息的结构SHTCTL
- sheet_refresh函数:这个函数会从下到上描绘所有的图层。refresh是“刷新”的意思。电视屏幕就是在1秒内完成多帧的描绘才做出动画效果的,这个动作就被称为刷新。而这种对图层的刷新动作,与电视屏幕的动作有些相似,所以我们也给它起名字叫做刷新。
- sheet_slide:不改变图层的高度而只上下左右移动图层的函数。
- sheet_free释放已使用图层的内存的函数。
struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize, int ysize) |
首先使用memman_alloc_4k来分配用于记忆图层控制变量的内存空间,这时必须指定该变量所占空间的大小,不过我们可以使用sizeof(struct SHTCTL)这种写法,让C编译器自动计算。只要写sizeof(变量型),C编译器就会计算出该变量型所需的字节数。
接着,我们给控制变量赋值,给其下的所有图层变量都加上“未使用”标签。
3.提高叠加处理速度(1)
- 只需要重新描绘鼠标移动相关的部分,也就是移动前后的部分就可以了,即256×2=512个像素。这只是64 000像素的0.8%而已,所以有望提速很多。现在我们根据这个思路写一下程序。
- 要在画面上显示坐标等信息,结果又执行了sheet_refresh程序。所以我们要解决图层内文字显示的问题。
4.提高叠加处理速度(2)
- 使不写入像素内容,也要多次执行if语句。我们最初就应该把for语句的范围限定在刷新范围之内。
void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1)
{
int h, bx, by, vx, vy, bx0, by0, bx1, by1;
unsigned char *buf, c, *vram = ctl->vram;
struct SHEET *sht;
for (h = 0; h <= ctl->top; h++) {
sht = ctl->sheets[h];
buf = sht->buf;
/* 使用vx0~vy1,对bx0~by1进行倒推 */
bx0 = vx0 - sht->vx0;
by0 = vy0 - sht->vy0;
bx1 = vx1 - sht->vx0;
by1 = vy1 - sht->vy0;
if (bx0 < 0) { bx0 = 0; } /* 说明(1) */
if (by0 < 0) { by0 = 0; }
if (bx1 > sht->bxsize) { bx1 = sht->bxsize; } /* 说明(2) */
if (by1 > sht->bysize) { by1 = sht->bysize; }
for (by = by0; by < by1; by++) {
vy = sht->vy0 + by;
for (bx = bx0; bx < bx1; bx++) {
vx = sht->vx0 + bx;
c = buf[by * sht->bxsize + bx];
if (c != sht->col_inv) {
vram[vy * ctl->xsize + vx] = c;
}
}
}
}
return;
}