1

30天自制操作系统——第二十二天图形处理

 2 years ago
source link: https://blog.csdn.net/mint1993/article/details/120499770
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

30天自制操作系统——第二十二天图形处理

水龙吟唱 2021-09-27 00:13:49 813
专栏收录该内容
22 篇文章 62 订阅

点是各种图形的基础,要实现图形处理就先从画点开始。创建窗口的程序之前写过了,忘记的话往前翻翻找一下。再给窗口来一个黑色背景,窗口名就叫“夜空中最亮的星”吧。

画点API式样:

画点API:
EDX=11
EBX=窗口句柄
ESI=显示位置的x的坐标
EDI=显示位置的y坐标
EAX=色号

a_nask.nas节选:

_api_point:		; void api_point(int win, int x, int y, int col);
		PUSH	EDI
		PUSH	ESI
		PUSH	EBX
		MOV		EDX,11
		MOV		EBX,[ESP+16]	; win
		MOV		ESI,[ESP+20]	; x
		MOV		EDI,[ESP+24]	; y
		MOV		EAX,[ESP+28]	; col
		INT		0x40
		POP		EBX
		POP		ESI
		POP		EDI
		RET

夜空中最亮的星,star.c:

int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
void api_initmalloc(void);
char *api_malloc(int size);
void api_point(int win, int x, int y, int col);
void api_end(void);

void HariMain(void)
{
	char *buf;
	int win;
	api_initmalloc();
	buf = api_malloc(150 * 100);
	win = api_openwin(buf, 450, 300, -1, "The brightest stars");
	api_boxfilwin(win,  6, 26, 443, 293, 0 /* 黑色 */);
	api_point(win, 225, 150, 3 /* 黄色 */);
	api_end();
}

make run一下——

在这里插入图片描述

“夜空中最亮的星”好像并没有那么闪亮,屏幕上有点灰还真不容易看的见。

那么我们来让星星布满整个夜空吧(听起来有点中二),星星也可以不是黄色的,红色、蓝色的星星也可以有,我们来画一个彩色的星空好了。

彩色星空,stars.c

int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
void api_initmalloc(void);
char *api_malloc(int size);
void api_point(int win, int x, int y, int col);
void api_end(void);

int rand(void);		/* 0 ~32767随机数*/

void HariMain(void)
{
	char *buf;
	int win, i, x, y ,c;
	api_initmalloc();
	buf = api_malloc(150 * 100);
	win = api_openwin(buf, 450, 300, -1, "stars");
	api_boxfilwin(win,  6, 26, 443, 293, 0 /* 黑色 */);	
	for (i = 0; i < 500; i++) {
		x = (rand() % 437) + 6;
		y = (rand() % 267) + 26 ;
		c = rand() % 15 ;
		
		api_point(win, x, y, c /* 黄色 */);
	}
	api_end();
}

rand函数我们比较熟悉,用于产生0 ~ 32767的随机数,而对437取余就会得到0 ~ 436的随机数。

make run一下——

在这里插入图片描述

画的密密麻麻,这回看清楚了,不过彩色的星空好像没想象中好看呢。

接下来我们实现画直线的功能,画直线我们需要知道起始点的坐标,直线的颜色。

API式样:

在窗口上画直线
EDX=13
EBX=窗口句柄
EAX=x0
ECX=y0
ESI=x1
EDI=y1
EBP=色号

a_nask.nas节选:

_api_linewin:		; void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
		PUSH	EDI
		PUSH	ESI
		PUSH	EBP
		PUSH	EBX
		MOV		EDX,13
		MOV		EBX,[ESP+20]	; win
		MOV		EAX,[ESP+24]	; x0
		MOV		ECX,[ESP+28]	; y0
		MOV		ESI,[ESP+32]	; x1
		MOV		EDI,[ESP+36]	; y1
		MOV		EBP,[ESP+40]	; col
		INT		0x40
		POP		EBX
		POP		EBP
		POP		ESI
		POP		EDI
		RET

画彩色直线,lines.c:

int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
void api_initmalloc(void);
char *api_malloc(int size);
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
void api_end(void);

void HariMain(void)
{
	char *buf;
	int win, i;
	api_initmalloc();
	buf = api_malloc(160 * 100);
	win = api_openwin(buf, 460, 300, -1, "lines");
	for (i = 0; i < 8; i++) {
		api_linewin(win + 1,  8, i * 30 + 26, 450, i * 30 + 26, i);
		
	}
	api_refreshwin(win,  6, 26, 454, 290);
	api_end();
}

执行make run——

在这里插入图片描述

画出来的直线,看起来有点像小时候练习拼音用的那种拼音簿。

接下来我们可以做个好玩点的,比如一个能动的小程序。

walk.c节选:

void HariMain(void)
{
	char *buf;
	int win, i, x, y;
	api_initmalloc();
	buf = api_malloc(160 * 100);
	win = api_openwin(buf, 160, 100, -1, "walk");
	api_boxfilwin(win, 4, 24, 155, 95, 0 /* 黑色 */);
	x = 76;
	y = 56;
	api_putstrwin(win, x, y, 3 /* 黄色 */, 1, "@");
	for (;;) {
		i = api_getkey(1);
		api_putstrwin(win, x, y, 0 /* 黑色 */, 1, "@"); /* 用黑色擦除 */
		if (i == '4' && x >   4) { x -= 8; }
		if (i == '6' && x < 148) { x += 8; }
		if (i == '8' && y >  24) { y -= 8; }
		if (i == '2' && y <  80) { y += 8; }
		if (i == 0x0a) { break; } /* 按回车键结束 */
		api_putstrwin(win, x, y, 3 /* 黄色 */, 1, "@");
	}	
	api_closewin(win);
	api_end();
}

这个程序可以让“@”在窗口中移动,按键 2 、 4、 6、 8分别对应上下左右,按键 5 回到窗口中心。

执行make run——

在这里插入图片描述
注:本文参照《30天自制操作系统》制作,感谢各位的持续关注,原著源码链接见第十九篇。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK