30天自制操作系统------图形处理相关
来源:互联网 发布:怎么找放单的淘宝商家 编辑:程序博客网 时间:2024/06/09 16:20
一、编写malloc
每个应用程序至少都需要一个窗口,窗口的内容需要保存在一块内存中,我们原来的做法是使用固定大小的数组如buf[320*200],然后往里面填写东西,但是这样子的后果就是应用程序的.hrb文件比较大,使用二进制文件打开.hrb文件发现里面有很多“00”。原因就是数组的声明就相当于汇编中的RESB指令,在内存中给为数组预留出了数组所需要的空间。
为了减小.hrb的大小,我们需要编写malloc函数,虽然说以前已经有一个memman_alloc函数,但是因为memman_alloc函数分配的内存空间并不位于应用程序的数据段范围内,所以我们需要编写一个为应用程序分配内存空间的API函数,然后将malloc的内存空间的首地址写到.hrb文件当中去,这样就可以有效减少.hrb文件的大小。
malloc函数若想要实现分配内存的功能,那么操作系统就需要提前给应用程序预留一定大小的空间用于malloc,因为应用程序所需要的内存空间无法预测,最好的做法是用于给malloc函数分配的内存空间可以调整大小,但是在我们自制的操作系统中没有实现这样的功能,只能给malloc函数预留一定大小的空间,这也算是一个需要优化的地方。
当然malloc函数还是需要对应的free函数。
编写API函数malloc的思路:
(1)使用memman_init函数初始化一个memman,参数中的地址要写应用程序段的地址;
(2)使用memman_free函数释放空间,为应用程序的malloc预留这段空间;
(3)使用memman_alloc函数为应用程序分配空间;
(4)应用程序结束时使用memman_free函数释放空间。
虽然memman_init,memman_alloc,memman_free这几个函数都只能在操作环境下使用,但是还是可以通过API的方式来进行调用。
二、画点/画线
每个任务都要有个窗口,也就是说每个任务都要有占用一个图层,想要在任务的界面上显示一些内容,只需要在对应的图层的buf中填写相应的内容,然后刷新图层即可。图层SHEET的定义如下:
struct SHEET{unsigned char *buf; /*用来记录图层上所描画内容的地址*/int xsize,ysize,x,y,color,height,flags;struct SHTCTL *ctl;};
(1)若要在窗口上显示一个点,那么就在对应图层的buf中修改一个单元的内容即可。
(2)若要在窗口上显示多个点,那么就在对应图层的buf中修改多个单元的内容即可。
(3)点动成线,可以画点就可以画线,两点确定一条直线,只要确定了线的起点坐标和终点坐标,就可以画出这条线。
画线的思路:
设起点(x0,y0)终点(x1,y1)
①求横纵坐标的差值:dx=x1-x0,dy=y1-y0
②求横纵坐标差值的绝对值:dx=|dx|,dy=|dy|
③比较dx和dy,确定点的个数len:
a.若dx>=dy,len=dx+1,dx=1,dy=dy/len,若x0<x1,dx=-dx,若y0<y1,dy=-dy
b.若dx<dy,len=dy+1,dy=1,dx=dx/len,若x0<x1,dx=-dx,若y0<y1,dy=-dy
④ x=x0,y=y0
按如下方式画len个点:画点(x,y),x+=dx,y+=dy。
三、关闭窗口
应用程序结束之后其窗口应该关闭,一直留在桌面也不好看。
应用程序的窗口都对应一个图层,要想关闭应用程序的窗口,只需要将其所对应的图层的内存所释放即可,之前编写sheet.c时就有一个实现此功能的函数sheet_free(),我们只需要在API函数api_closewin中调用该函数即可。
想要实现按下某个键任务窗口关闭的功能,我们需要API实现如下功能get_key(),返回值为按键编码:
我们使用汇编语言编写该函数,在该函数中使用INT 0x40调用API,所以获取按键编码的工作实际上是hrb_api函数完成的。
hrb_api函数为该功能分配的功能号为15,15号功能的工作原理如下
(1)改造TASK的结构,为其增加一个FIFO成员,如下:
struct TASK{int sel,flags; /*sel用来存放GDT的编号*/int level;int priority;/*优先级*/struct FIFO fifo;struct TSS tss;};
(2)让TASK的FIFO来接收数据
(3)若FIFO为空,任务休眠
(4)若FIFO不为空,取出FIFO中的数据,对不同的数据做出不同的处理,若是键盘输入的数据,将按键编码返回,作为get_key()函数的返回值。
按照以上思路来编写应用程序时,程序结束之前会进入死循环,每次都判断get_key()的结果,判断它是否是我们指定的按键编码,若是则跳出循环,关闭窗口。
四、强制结束并关闭窗口
第三部分解决的是正常关闭窗口的思路,但是在强制结束任务时,窗口还是不会关闭。应用程序时在cmd_app函数中通过start_app来启动的,当应用程序执行完毕之后或者被强制结束后都会返回到cmd_app中执行start_app后的程序,利用这一点,我们可以在start_app调用结束后,释放任务对应的图层所使用的空间。
为了能将TASK和SHEET对应,我们在SHEET中又添加了TASK成员,添加之后的SHEET结构如下:
struct SHEET{unsigned char *buf; /*用来记录图层上所描画内容的地址*/int xsize,ysize,x,y,color,height,flags;struct SHTCTL *ctl;struct TASK *task; /*该图层的任务*/ };
在生成新的窗口时将对应的图层和任务进行绑定,在结束任务时,将任务对应的图层的内存进行释放即可。
- 30天自制操作系统------图形处理相关
- 30天自制操作系统
- 30天自制操作系统
- 30天自制操作系统
- 30天自制操作系统
- [读书笔记]30 天自制操作系统 day10 叠加处理
- 30天自制操作系统 导读
- [30天自制操作系统]day_2
- 30天自制操作系统day00
- 30天自制操作系统day01
- 30天自制操作系统day02
- 30天自制操作系统(1)
- 30天自制操作系统day2
- 30天自制操作系统day3
- 30天自制操作系统day4
- 30天自制操作系统day5
- 30天自制操作系统day7
- 30天自制操作系统day8
- Java学习笔记(二)——类和对象
- Linux编程环境
- 2017最新搭建hustoj网站
- 字符串的包含
- mysql如何实现oracle的start with
- 30天自制操作系统------图形处理相关
- 将postgresql数据库内容导出至sqlite数据库
- 程序方法
- 快速排序及其改进
- Android
- LintCode 97 验证二叉查找树
- STL学习笔记-迭代器
- python中 Jupter的使用 notebook
- 各大巨头纷纷出手 数据中心市场硝烟弥漫