30天自制操作系统------图形处理相关

原创 2017年07月17日 17:25: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_initmemman_allocmemman_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|

         ③比较dxdy,确定点的个数len

        a.dx>=dylen=dx+1dx=1dy=dy/len,若x0<x1dx=-dx,若y0<y1dy=-dy

        b.dx<dylen=dy+1dy=1dx=dx/len,若x0<x1dx=-dx,若y0<y1dy=-dy

         ④ x=x0y=y0  

     按如下方式画len个点:画点(x,y),x+=dxy+=dy


三、关闭窗口

    应用程序结束之后其窗口应该关闭,一直留在桌面也不好看。

应用程序的窗口都对应一个图层,要想关闭应用程序的窗口,只需要将其所对应的图层的内存所释放即可,之前编写sheet.c时就有一个实现此功能的函数sheet_free(),我们只需要在API函数api_closewin中调用该函数即可。

想要实现按下某个键任务窗口关闭的功能,我们需要API实现如下功能get_key(),返回值为按键编码:

我们使用汇编语言编写该函数,在该函数中使用INT 0x40调用API,所以获取按键编码的工作实际上是hrb_api函数完成的。

hrb_api函数为该功能分配的功能号为1515号功能的工作原理如下

   1)改造TASK的结构,为其增加一个FIFO成员,如下:

    

struct TASK
{
	int sel,flags;  /*sel用来存放GDT的编号*/
	int level;
	int priority;	/*优先级*/
	struct FIFO fifo;
	struct TSS tss;
};

   2)让TASKFIFO来接收数据

   3)若FIFO为空,任务休眠

   4)若FIFO不为空,取出FIFO中的数据,对不同的数据做出不同的处理,若是键盘输入的数据,将按键编码返回,作为get_key()函数的返回值。

按照以上思路来编写应用程序时,程序结束之前会进入死循环,每次都判断get_key()的结果,判断它是否是我们指定的按键编码,若是则跳出循环,关闭窗口。

 

 

四、强制结束并关闭窗口

第三部分解决的是正常关闭窗口的思路,但是在强制结束任务时,窗口还是不会关闭。应用程序时在cmd_app函数中通过start_app来启动的,当应用程序执行完毕之后或者被强制结束后都会返回到cmd_app中执行start_app后的程序,利用这一点,我们可以在start_app调用结束后,释放任务对应的图层所使用的空间。

为了能将TASKSHEET对应,我们在SHEET中又添加了TASK成员,添加之后的SHEET结构如下:

 

struct SHEET
{
	unsigned char *buf;  /*用来记录图层上所描画内容的地址*/
	int xsize,ysize,x,y,color,height,flags;
	struct SHTCTL *ctl;
	struct TASK *task; /*该图层的任务*/ 
}; 

在生成新的窗口时将对应的图层和任务进行绑定,在结束任务时,将任务对应的图层的内存进行释放即可。



相关文章推荐

《30天自制操作系统》纸娃娃操作系统以及大多数操作系统的加载原理

最近在读《30天自制操作系统》这本书,在读到“从启动区加载操作系统”这一小节的时候卡住了,首先我的疑问是这样的:首先,磁盘映像文件img的0x2600这个地方存储着操作系统文件的名称(用二进制编辑器看...

QT5入门之9 - 菜单栏

如上文,新建项目Qt Widgets Application。 MainWindow头文件中添加动作和动作相应函数声明。 private: Ui::MainWindow *ui; Q...

图形处理相关资源(面部识别、姿态估计、变形、、、)

2D 影像变形(Morphing),是由一张图像流畅地变成另一张图像的视觉效果,最常见的应用是由一张人脸影像变化到另一张人脸影像cross-dissolving + warpingDemo ...

图形处理(十一)Stroke Parameterization

转眼已经过去了好几年,最近开始写技术博客,是为了回顾。《Stroke Parameterization》这篇paper是我人生写的第一篇作者没有提供代码的文章,也是初次学会阅读外文文献的开始。三年前菜...

第10章 Winodws图形处理与文本输入输出

在MFC程序设计中,屏幕的绘图是通过设备环境实现的,它是图形设备接口的重要元素。它代表了具体的物理设备,隐藏了物理设备的差异,例如打印机和屏幕之间的差异。设备的无关性使得用户不用关心具体的物理设备的显...

VTK图形处理之抽取轮廓

等值面(线)  等值面(线)提取是一种常用的可视化技术。在医学图像处理中,由于CT、MRI等图像分辨率越来越高,虽然体绘制技术可以清晰得对数据内部结构进行可视化,但是其计算量和效率却制约了其使用。此时...

图形处理(九)点云重建(下)法矢求取、有向距离场等值面提取

1、点云预处理 。这一步主要是点云滤波、采样、移除离群点等操作,涉及到的经典算法有MLS、双边滤波、WLOP等,这些在我的另外一篇博文中,有比较详细的介绍。 2、重建网格曲面。这一步主要涉及相关经...
  • hjimce
  • hjimce
  • 2015年06月08日 22:44
  • 3052

图形处理(十二)拉普拉斯网格优化、最小二乘网格模型光顺

这里要分享的paper,是通过拉普拉斯的方法实现三角网格模型的优化。如果你已经非常熟悉三角网格曲面的拉普拉斯相关理论,实现这篇paper也就非常容易了。网格曲面的拉普拉斯坐标不但可以用于变形、光顺,还...
  • hjimce
  • hjimce
  • 2015年06月15日 17:22
  • 4319

java图形处理-Java 2D

Java2D介绍
  • nlznlz
  • nlznlz
  • 2015年12月03日 01:42
  • 291
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:30天自制操作系统------图形处理相关
举报原因:
原因补充:

(最多只允许输入30个字)