30天自制操作系统之叠加处理
文章目录
- 前言
- 加快更新速度
- 闪烁问题
- 其一
- 其二
前言
- 我们通过往显存Vram里面直接设置像素的颜色来设置显示某个对象
- 对于数字或者字母,我们将其显示放置在一个16*16的数组当中,然后将其遍历,显示在画面的某个位置
static char cursor[16][16] = {"**************..","*OOOOOOOOOOO*...","*OOOOOOOOOO*....","*OOOOOOOOO*.....","*OOOOOOOO*......","*OOOOOOO*.......","*OOOOOOO*.......","*OOOOOOOO*......","*OOOO**OOO*.....","*OOO*..*OOO*....","*OO*....*OOO*...","*O*......*OOO*..","**........*OOO*.","*..........*OOO*","............*OO*",".............***"};
加快更新速度
- 对于叠加处理,SheetFresh是核心
- 他将处于显示的层,从高到低依次绘制。这样会导致,鼠标只要稍微移动就会重新绘制,字符进行更新的时候也会重新绘制
for (h = 0; h <= ctl->top; h++) {sht = ctl->sheets[h];buf = sht->buf;for (by = 0; by < sht->bysize; by++) {vy = sht->vy0 + by;for (bx = 0; bx < sht->bxsize; bx++) {vx = sht->vx0 + bx;c = buf[by * sht->bxsize + bx];if (c != sht->col_inv) {vram[vy * ctl->xsize + vx] = c;}}}}
- 一开始只有3层,每一次重新绘制需要刷新 3 * 320 * 640 = 614400个像素,这是一个巨大的浪费。
- 但是对于鼠标的移动而言,我们只要更新移动前的区域和移动后的区域就可以了
- 对于字符的每一次更新,也只需要更新指定的区域即可。
- 因此就可以对SheetFresh进行重写SheetFreshSub
- 但是SheetFreshSub的实现是基于一个if判断,即对所有的层的坐标进行判断,如果在指定的范围内就继续向下执行,取颜色然后更新Vram
void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1)
{int h, bx, by, vx, vy;unsigned char *buf, c, *vram = ctl->vram;struct SHEET *sht;for (h = 0; h <= ctl->top; h++) {sht = ctl->sheets[h];buf = sht->buf;for (by = 0; by < sht->bysize; by++) {vy = sht->vy0 + by;for (bx = 0; bx < sht->bxsize; bx++) {vx = sht->vx0 + bx;if (vx0 <= vx && vx < vx1 && vy0 <= vy && vy < vy1) {c = buf[by * sht->bxsize + bx];if (c != sht->col_inv) {vram[vy * ctl->xsize + vx] = c;}}}}}return;
}
- 这样会平白无故的执行很多次if语句,原来都是对于buf数组,bx=0,by = 0 开始
- 其实我们只需要根据指定的Vx, Vy 范围然后反推出其bx,by即可,即重新推导出for循环的范围
- 然后在这种情况下有三种情况
- 第一是,整个层级恰好落在范围内
- 第二是,整个层级左半边在范围内或者整个层级右半边在范围内
- 第三是,整个层级完全在范围之外【这种情况下,要么x全部小于0,要么全部大于xsize,因为无法通过bx<bx1的判断,for循环直接退出】
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; }if (by0 < 0) { by0 = 0; }if (bx1 > sht->bxsize) { bx1 = sht->bxsize; }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;}}}
闪烁问题
其一
- 首先我们设置一个持续累加的数字Count,然后在窗口进行显示,会发现该窗口不停的闪烁
- 问题在于,SheetFresh刷新的时候是总是从下往上刷新,因此数字会暂时的消失,然后又出现。
- 解决办法就是——在刷新的时候指定一个高度,对于指定高度以上的进行画面刷新
- 当图层移动的时候,原先位置的低层级会显示出来,所以从0到top进行刷新,而新位置的高层级受到影响,从height到top进行刷新
- 当图层只是单纯的SheetFresh的时候,只需要从其当前height到top更新即可
- 当图层只是单纯的改变层级时,有很多情况,具体分析。
其二
- 这样依旧会有问题,当鼠标停放在窗口上面的时候,会发现鼠标在不停的闪烁
- 问题还是存在,我们仅仅需要刷新该图层所占据的像素,而鼠标的层级高于图层,所以其重叠的部分不需要刷新
- 解决办法就是——新建一个和Vram同样大小的数组Map,然后在写入颜色的地方更改为写入其层级SID,最后在SheetFresh的时候,根据height和Map只刷新该层即可
vx = sht->vx0 + bx;if (buf[by * sht->bxsize + bx] != sht->col_inv) {map[vy * ctl->xsize + vx] = sid;}
- 我们需要更新Map,在SheetSlide即层级移动,和SheetUpDown更改层级时。然后在SheetFresh时使用Map
vx = sht->vx0 + bx;if (map[vy * ctl->xsize + vx] == sid) {vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx];}
30天自制操作系统之叠加处理相关推荐
- 【操作系统】30天自制操作系统--(9)叠加处理
这一章主要是处理之前遇到的图层叠加的问题.[操作系统]30天自制操作系统--(7)鼠标移动与32位切换 一 内存管理优化 上一章的内存管理虽然写好,但是还是有不完善的地方.因为如果不对申请内存的大小有 ...
- 为什么《30天自制操作系统》封面中的猫是两只尾巴
刚刚在一社区,发了一贴,被指出一问题,询一高人,得一答案.这便是我没有关注到的封面上的那只猫,我想这也是很多读者没有关注到的.因为在我微博的200转发贴中,并没有人提到封面中的猫为何有两只尾巴.于是咨 ...
- 发布在《30天自制操作系统》之前的帮助阅读贴
说明:这是8月15日即将上市的一本新书,本文的摘选也可以命名为<30天自制操作系统>上市之前必读.本书幽默,有趣,可以说是技术书里的幽默书,让您读起来绝对不会感到乏味.在本书上市之前,您一 ...
- 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!
<30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的 ...
- 写在《30天自制操作系统》上市之前
这本<30天自制操作系统>马上就要在各大书店和网上商城全面上架了,作为本书的4位译者之一,我负责翻译了本书约三分之二的内容.这是我参与翻译的第一本译著,我感到很激动也很紧张,因为我知 ...
- 《30天自制操作系统》笔记(04)——显示器256色
<30天自制操作系统>笔记(04)--显示器256色 进度回顾 从最开始的(01)篇到上一篇为止,已经解决了开发环境问题和OS项目的顶层设计问题. 本篇做一个小练习:设置显卡显示256色. ...
- 《30天自制操作系统》学习笔记--第好多天
之前看<30天自制操作系统>,参考而成,和书中系统并不完全一致,是在原有基础上按照自己的习惯而成,由于水平和工作原因,未完成内存管理和文件系统,有兴趣者可以通过以下网址https://gi ...
- 由《30天自制操作系统》引发的漫画创作
大家可还记得<30天自制操作系统>的封面上的那只猫吗?记得当时,在果壳网有人问,为何这只猫长了两只尾巴呢,延着这条线,我把这本书捧上了展示的舞台.事隔四个多月,我又重提此书. 这本经我手宣 ...
- 30天自制操作系统——第二十三天窗口操作
窗口及输入切换 我们先来实现用键盘切换窗口,按下F11键,将最下面的窗口移动到最上面,这里F11按键的编码为0x57. bootpack.c节选: void HariMain(void) {(略)fo ...
- 30天自制操作系统-初体验
最近在图书馆翻阅关于操作系统的书籍,看到川和秀实的自制操作系统决定也动手尝试一下,这本书书名就叫做30天自制操作系统.首先还是附上光盘镜像的获取地址吧.30天自制操作系统光盘镜像ISO完整版下载 - ...
最新文章
- mysql group by 报错 ,only_full_group_by 三种解决方案
- spark rdd saveAsTextFile保存为文件
- boost::gil::threshold_truncate用法的测试程序
- 读取当前linux进程内存_(笔记)Linux上的内存分配
- 《剑指Offer》 不用加减乘除做加法
- SQL Server商业智能功能– SQL Server数据工具–商业智能
- 华泰证券 python 自动交易软件_为何选用股票自动交易助手
- Centeros常用命令
- iphone快捷指令一键重启_iOS捷径一键重启教程 苹果手机一键重启方法
- 微软Kinect for windows SDK 使用教程一 (NUI部分)
- 使用Hostapd开启AP功能
- ToolsCodeTemplate使用
- 【Spring+Mybatis】 Invalid bound statement (not found): com.xxxx.mapper.UserMapper.selectUser
- Golang观察者设计模式(十九)
- Springboot 整合 Current-Limiting 实现接口限流
- 域名证书和SSL证书一样的吗?有什么区别呢
- opencv-python中 boundingRect(cnt)以及cv2.rectangle用法
- 拆解碧桂园2021投资版图,是主动“扩张”还是被动“焦虑”?
- stm32---端口复用和重映射
- 1 实验9_7_设计函数int getVowel(char str[],char vowel[]); (100分)
热门文章
- 1003 我要通过! (20 分)—PAT (Basic Level) Practice (中文)
- 代码编辑器[0] - Vim/gVim[1] - Vim 的快捷键操作
- SQL 函数NULLIF、NULL、ISNULL、COALESCE、IIF
- python之路-基础篇-002
- android api 中文 (74)—— AdapterView.AdapterContextMenuInfo
- Android文字的复制和粘贴
- (原创)倾情奉献由测试兵团整理的cmh格式测试管理资料
- IDEA 中git使用非默认ssh客户端进行登录
- 使用group by rollup和group by cube后的辅助函数
- 腾讯云启动 tomcat 很慢的问题