第10天:叠加处理

1、内容1:内存管理

因为bootpack.c太长了,所以创建一个memory.c,将bootpack里的一部分内容分到memory中,使bootpack.c的代码变短。

在之前的内存管理函数中,memman_alloc和memman_free是以1字节为单位进行内存管理的,虽然这样没啥问题,但是分配过小的话,在反复进行内存分配和内存释放之后,内存中就会出现很多不连续的小段未使用空间,这样会把man->frees消耗殆尽。
因此,编写一些以0x1000(即4KB)字节为单位进行内存分配和释放的函数,这些函数还实现了把指定的内存大小按4KB为单位向上舍入。
增加的部分:7a中的memory文件

这次的程序最关键的部分是向上舍入的部分,即size = (size + 0xfff) & 0xfffff000;
为什么要实现向上舍入?
因为在之前的内存管理中,将将 内存分成了0x1000字节大小的块,然后分配给程序使用,但并不是所有的程序用到的都是0x1000的整数倍字节,所以要设计一个取整的方法。在这里,作者采用的取整的方法就是向上舍入的取整。
size = (size + 0xfff) & 0xfffff000;首先将size加上0xfff,再将末尾三位置为0,若size形如abc000,那么结果就是abc000;若size形如abcxxx,也就是末三位不全为0,那么结果为ab(c+1)000,这个结果也符合向上取整的定义。
实验结果:

一切正常。

2、内容2:叠加处理

之前由于鼠标的叠加处理没有设计好,导致状态栏会被鼠标所吃掉。因此,在这个内容中,设计了一个叠加程序,使得其不仅适用于鼠标的叠加处理,也能适用于窗口的叠加处理。

在这个画面中,能清楚看到图层的代表意义,最上面的小图层用来描绘鼠标指针,它下面的几张图层是用来存放窗口的,而最下面的一张图层是用来存放存放和桌面壁纸。同时,还要通过移动图层的方法来实现鼠标指针的移动以及窗口的移动。
首先定义一个结构体,该结构体中,包含用于记录图层上所描画内容的地址buf,图层的整体大小,也就是长、宽,分别为bxsize和bysize。表示图层在画面上位置的坐标vx0和vy0,透明色色号col_inv,图层高度height和存放有关图层的各种设定信息的flag。
7b的bootpack.h文件

当然,如果只有一个图层,是不能实现图层的叠加处理的,因此,便有了管理多重图层信息的结构:7b的bootpack.h文件

创建一个SHTCTL结构体,MAX_SHEETS表示能够管理的最大图层数,暂时设为256。
VRAM里的地址和画面的大小由vram、xsize、ysize来表示。Top表示最上面一层的高度,sheets0用来存放准备的图层的信息,sheets是记忆地址变量的领域。

在图层控制变量中,sheets0的部分大小就有32x256=8192,即8KB,如果再加上sheets的话,就超过了9KB。对于其的空间需求,使用memman_alloc_4k来分配内存空间。
首先使用memman_alloc_4k来分配记忆图层控制变量的内存空间,指定该变量所占空间的大小,通过sizeof,让编译器自动计算出该变量型所需的字节字节数,然后给控制变量赋值,给其下的所有图层变量都加上“未被使用的”标签,也就是flags=0。
7b中的sheet文件

分配好内存空间后,还需要取得新生成的未使用图层的,即:7b中的sheet文件

在之前所定义的sheets0[]中寻找未使用的图层,如果找到了,就将其标志为“正在使用”,即改变flags的值,使其变为1,并返回其地址。将高度设为1,即表示图层的高度还没有被设置,图层处于隐藏状态。
最重要的一步便是设定底板高度,因为高度决定着图层的显示。首先保存存储设置前的高度信息,如果设定的高度过高或者过低,都需要先矫正,比如height<-1时,就需要将高度设为-1。
当设定高度之后,就需要对sheets[]进行重新排列,这样才能在之后正确的显示出来。如果设定的高度比之前的高度低,并且,设定的高度是大于-1的话,那么就需要将之前的高度以上的图层向上移动一层,将所设定的高度插入。如果设定的高度是小于-1的,那么也就是要将该图层隐藏,所以将该图层以上的图层的高度向下一个,并矫正最高层的高度。
如果设定的高度比以前的高度高的话,并且以前的高度是大于0的话,那么就需要将以前高度到现在所设定高度的图层向下一层,为该高度的图层空出一层存放。如果以前的高度是-1,也就是处于隐藏状态的话,就将以上所有图层向上一层,即已显示的图层要增加一个,即最高层的高度增加1。修改好高度之后,便可以按新图层信息就行绘制画面。
修改的程序如下:7b中的sheet文件

设计图层刷新函数,通过刷新函数,实现从下到上描绘所有的图层,对于已经设定好高度的多有图层来说,需要从下往上的,将透明色以外的所有像素都赋值到VRAM中,因为是从下往上开始复制的,所以最上面的内容就留在了画面上。
相关函数如下:7b中的sheet文件

除此以外,还需要有可以上下左右移动指定图层的函数,并不改变图层的高度。也就是sheet.c中的slide函数。
相关函数:7b中的sheet文件

释放已使用图层的内存的函数sheet_free。7b中的sheet文件

首先准备两个图层,分别是sht_back和sht_mouse,两个缓冲区buf_back和buf_mouse,用于描绘图形。在每次修改缓冲区之后,都需要进行图层刷新。
7b中的bootpack文件

运行结果:

由于使用内存的增加,导致剩余内存相对减少。

3、内容3:提高叠加处理速度(1)

在内容二中,虽然最后结果显示是正确的,但是在这里操作时,会发现反应比较慢。因此就需要提高速度,首先看看在图层的移动中,有没有可以改进的地方。指针的移动,鼠标指针虽然最多只有16x16(即256)个像素,但是根据之前所设计的,只要鼠标指针发生移动,那么就需要重新描绘移动相关的部分,也就是256x2个像素,虽然这些占比比较少,但是还是可以通过修改其来实现提速的目的。7c中的sheet文件:
在图层刷新的函数中,我们增加一个if语句,来实现其试用vx0~vy1指定所要刷新的范围。

实现指定刷新范围功能最关键的就是标红的一句,即if (vx0 <= vx && vx < vx1 && vy0 <= vy && vy < vy1) ,只有当vx0~vy1满足这其中所有的条件时,才进行刷新。
修改slide函数,来提高它的运行速度。7c中的sheet文件:

首先记住图层移动前的显示位置,然后再设定新的显示位置,最后只需要重新描绘移动前和移动后的地方即可。
虽然这样改理论上能提高运行速度,但是在移动鼠标时,由于要在画面上显示坐标等信息,又执行了sheets_refresh函数,所以还是很慢,因此就需要解决图层文字显示上的问题。在图层上显示文字,实际上并不是改写图层的所有内容,只需要改写文字部分的像素的内容即可。
重新编写sheet_refresh函数:7c中的sheet文件:

这里的指定范围,并不是直接指定画面内的坐标,而是指定缓冲区内的坐标,这样HariMain就可以不考虑图层在画面中的位置了。除此以外,只有每次想buf_back中写入信息时,才会进行sheet_refresh。

4、内容4:提高叠加处理速度(2)

虽然按照之前的做法,速度有了一定的改变,但如果还想要更加快一些的话,还是需要对efreshsub函数进行修改。在原函数中,即使不写入像素内容,也需要多次执行if语句。即便只刷新图层的一部分,也要对所有图层的全部像素执行if语句,来判断是否写入。而对于刷新范围以外的部分,即使执行了判断,最后也不会进行刷新,这样便造成了资源的浪费,减慢了刷新的速度。因此可以将for循环的范围限定在刷新范围之内。

修改的代码如下:7d中的sheet文件

改良的关键在于,bx在for语句中并使在0bxsize间循环,而是在bx0bx1之间循环,对于by也相同。而bx0和bx1均是通过刷新范围倒推得到。

计算vx0的坐标相当于bx中的哪个位置,然后把它作为bx0,其它坐标的处理方法也一样。

当处理刷新范围在图层外侧时,即sht_back中写入字符并进行刷新,并且刷新范围的一部分被鼠标覆盖时。

在这里,需要进行重复描绘的只有与鼠标图层重叠的那一小块范围,而其他部分并没有被要求刷新,所以不能刷新,这样的话,可以把bx0和by0都置为0。
当有不同的重叠方式时,比如:

在这种能够情况下,bx0和by0虽然都可以从vx0和vy0中顺利求取,但是bx1和by1就变得太大了,超出了图层的范围,所以要执行以下操作。

第三种可能面临的情况是完全不重叠的情况,这是是不需要进行重复描绘的,此时利用倒推计算得出的bx0和bx1都是负值,而在第一种情况中,只有bx0被修正为0,而在第二种情况中国,bx1没有被修正,还是负值。这样for循环便不会执行,这样就不会重复描绘了。
实行之后,速度变得比之前都要快了。

二、遇到的问题及解决方法

1、问题1: 设计一个窗口,点击X可以将窗口关闭。
解决方法:在一开始的想法是,直接设计一个描画窗口的函数,在鼠标点击X之后,再用一个窗口进行覆盖,这样处理之后,虽然能够实现想要的功能,但是当鼠标再该区域移动时,又会刷新画面,导致又出现窗口。
后来参考了第11天的内容,选择用图层来做,首先也是设计一个描画窗口的函数。再graphic.c中添加一个window函数,该函数的功能是,描画窗口。

需要注意的是,要注意在bootpack.h中声明。

设计好窗口之后,要在HariMain中使用的话,模仿鼠标的显示,添加代码。

为窗口图层分配内存:


调用函数,并且将窗口图层的高度设为1,背景的高度设为0,鼠标的高度设为2。

当鼠标的左上角的坐标位于X的范围内时,并且鼠标发生了点击,即L,则将窗口图层的高度设为-1,将其进行隐藏。

实验结果:

点击X之后:

30天自制操作系统(day10)相关推荐

  1. 为什么《30天自制操作系统》封面中的猫是两只尾巴

    刚刚在一社区,发了一贴,被指出一问题,询一高人,得一答案.这便是我没有关注到的封面上的那只猫,我想这也是很多读者没有关注到的.因为在我微博的200转发贴中,并没有人提到封面中的猫为何有两只尾巴.于是咨 ...

  2. 发布在《30天自制操作系统》之前的帮助阅读贴

    说明:这是8月15日即将上市的一本新书,本文的摘选也可以命名为<30天自制操作系统>上市之前必读.本书幽默,有趣,可以说是技术书里的幽默书,让您读起来绝对不会感到乏味.在本书上市之前,您一 ...

  3. 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!

    <30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的 ...

  4. 写在《30天自制操作系统》上市之前

       这本<30天自制操作系统>马上就要在各大书店和网上商城全面上架了,作为本书的4位译者之一,我负责翻译了本书约三分之二的内容.这是我参与翻译的第一本译著,我感到很激动也很紧张,因为我知 ...

  5. 《30天自制操作系统》笔记(04)——显示器256色

    <30天自制操作系统>笔记(04)--显示器256色 进度回顾 从最开始的(01)篇到上一篇为止,已经解决了开发环境问题和OS项目的顶层设计问题. 本篇做一个小练习:设置显卡显示256色. ...

  6. 《30天自制操作系统》学习笔记--第好多天

    之前看<30天自制操作系统>,参考而成,和书中系统并不完全一致,是在原有基础上按照自己的习惯而成,由于水平和工作原因,未完成内存管理和文件系统,有兴趣者可以通过以下网址https://gi ...

  7. 由《30天自制操作系统》引发的漫画创作

    大家可还记得<30天自制操作系统>的封面上的那只猫吗?记得当时,在果壳网有人问,为何这只猫长了两只尾巴呢,延着这条线,我把这本书捧上了展示的舞台.事隔四个多月,我又重提此书. 这本经我手宣 ...

  8. 30天自制操作系统——第二十三天窗口操作

    窗口及输入切换 我们先来实现用键盘切换窗口,按下F11键,将最下面的窗口移动到最上面,这里F11按键的编码为0x57. bootpack.c节选: void HariMain(void) {(略)fo ...

  9. 30天自制操作系统-初体验

    最近在图书馆翻阅关于操作系统的书籍,看到川和秀实的自制操作系统决定也动手尝试一下,这本书书名就叫做30天自制操作系统.首先还是附上光盘镜像的获取地址吧.30天自制操作系统光盘镜像ISO完整版下载 - ...

  10. 《30天自制操作系统》---第一天

    <30天自制操作系统>---第一天 二进制编译与文本编译器大家用自己顺手的就可以,今天通过两种方法运行虚拟机,第一种通过作者提供的工具运行在QEMU中,第二种方法运行到VMWare中,直接 ...

最新文章

  1. CodeGen处理Synergy方法目录
  2. linux定时器多次,Spring 定时器执行两次
  3. ubuntu20.04编译openjdk8
  4. 通过企业分布式缓存共享运行时数据
  5. 众智日照分析软件_飞时达CAD日照分析计算软件FastSUN V14.0.1发布升级
  6. 物联网爆发 引发安全升级
  7. codeforces 597C (树状数组+DP)
  8. (转)Palantir: 神秘的大数据公司
  9. navicat运行db文件_在 Navicat for MongoDB 使用文档
  10. (C#.net)CAD二次开发 polyline多段线/line直线/曲线 break打断的方法
  11. 脚本、脚本语言、写脚本都是什么呀???
  12. 安卓初学者笔记(四):用白话讲明白Activity是什么
  13. 利用Python爬取公交地铁数据(TransBigData版)
  14. java 语音包_有人开发了马保国语音包
  15. office2019怎么在同一个窗口显示多个文件
  16. 聚焦医疗数字化,华为医疗物联网更懂智慧医疗
  17. RNN结构,双向LSTM,Transformer, BERT对比分析
  18. 微信/微博的图片处理?-android酷炫图片处理(下)
  19. 能把中文论文翻译成英文进行查重吗?
  20. python 字典 按值排序贺按键排序 得到一个新字典

热门文章

  1. 学习Java用英文教材
  2. [附源码]计算机毕业设计springboot动物保护协会网站
  3. 情人节快到了,我部署了一套情侣头像小程序,并过审了
  4. 读《About Face 4 交互设计精髓》8
  5. Android获得手机唯一设备ID号
  6. Renesas:配置中断的常规流程
  7. keras模型 鸾尾花数据集_TensorFlow 入门(鸢尾花数据集)(一)
  8. unity 3d原创制作射击游戏(全完整版+安卓apk编译)
  9. [战略]Fans未来战略--第3篇--以文会友
  10. Python爬虫爬取微信朋友圈的方法,感兴趣的朋友可以了解下