⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphics.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <draw.h>#include <event.h>#include "mahjongg.h"intfreeup(int d, Point p){	/* are we blocked from above? */	if(d == Depth -1 || (level.board[d+1][p.x][p.y].which == 0 &&			level.board[d+1][p.x+1][p.y].which == 0 &&			level.board[d+1][p.x][p.y+1].which == 0 &&			level.board[d+1][p.x+1][p.y+1].which == 0))		return 1;		return 0;}intfreeleft(int d, Point p){	/* blocked from the left? */	if(p.x == 0 || (level.board[d][p.x-1][p.y].which == 0 &&		level.board[d][p.x-1][p.y+1].which == 0)) 		return 1;	return 0;}intfreeright(int d, Point p){			if(p.x == Lx-2 || (level.board[d][p.x+2][p.y].which == 0 &&		level.board[d][p.x+2][p.y+1].which == 0))		return 1;	return 0;}intisfree(int d, Point p){	return (freeleft(d, p) || freeright(d, p)) && freeup(d, p);}voidclearbrick(int d, Point p){	level.board[d][p.x][p.y].which = 0;	level.board[d][p.x+1][p.y].which = 0;	level.board[d][p.x][p.y+1].which = 0;	level.board[d][p.x+1][p.y+1].which = 0;}voidresize(Point p){	/* resize to the size of the current level */	int fd;	fd = open("/dev/wctl", OWRITE);	if(fd >= 0){		fprint(fd, "resize -dx %d -dy %d", p.x, p.y);		close(fd);	}}voiddrawbrick(int d, int x, int y){	Point p;	Rectangle r;	p = Pt(x*(Facex/2)-(d*TileDxy), y*(Facey/2)-(d*TileDxy));	r = Rpt(p, addpt(p, Pt(Facex, Facey)));	r = rectaddpt(r, Pt(Depth*TileDxy, Depth*TileDxy));	draw(img, r, tileset, nil, level.board[d][x][y].start);	if(level.board[d][x][y].clicked)		draw(img, r, selected, nil, ZP);	if(level.l.d == d && eqpt(level.l.p, Pt(x, y)))		border(img, r, 2, litbrdr, level.board[d][x][y].start);	/* looks better without borders, uncomment to check it out with'em *///	r = Rpt(r.min, addpt(r.min, Pt(Tilex, Tiley)));//	draw(img, r, brdr, nil, ZP);}voiddrawlevel(void){	int d, x, y;	draw(img, img->r, background, nil, ZP);	for(d = 0; d < Depth; d++)		for(y = 0; y < Ly; y++)			for(x = 0; x < Lx; x++)				if(level.board[d][x][y].which == 1) 					drawbrick(d, x, y);	draw(screen, screen->r, img, nil, ZP);	flushimage(display, 1);}Brick *bmatch(int d, Point p){	int x, y;	int ld = d;	do {		for(y = 0; y < Ly; y++)			for(x = 0; x < Lx; x++)				if(level.board[ld][x][y].which == 1 && isfree(ld, Pt(x, y)) && !eqpt(Pt(x, y), p) && 					level.board[d][p.x][p.y].type == level.board[ld][x][y].type)								return &level.board[ld][x][y];	} while(--ld >= 0);	return nil;}intcanmove(void){	int d, x, y;	for(d = Depth - 1; d >= 0; d--) 		for(y = 0; y < Ly; y++) 			for(x = 0; x < Lx; x++) 				if(level.board[d][x][y].which == 1 && isfree(d, Pt(x, y)))					if(bmatch(d, Pt(x, y)) != nil)						return 1;	return 0;}voidhint(void){	Brick *b = nil;	int d = 0, x = 0, y = 0;	if(level.c.d != -1) {		if((b = bmatch(level.c.d, level.c.p)) != nil) {			d = level.c.d;			x = level.c.p.x;			y = level.c.p.y;		}	} else {		for(d = Depth - 1; d >= 0; d--) 			for(y = 0; y < Ly; y++) 				for(x = 0; x < Lx; x++) 					if(level.board[d][x][y].which == 1 && isfree(d, Pt(x, y)))						if((b = bmatch(d, Pt(x, y))) != nil)							goto Matched;	}Matched:	if(b != nil) {		level.board[d][x][y].clicked = 1;		b->clicked = 1;		drawlevel();		sleep(500);		if(level.c.d == -1)			level.board[d][x][y].clicked = 0;		b->clicked = 0;		drawlevel();		sleep(500);		level.board[d][x][y].clicked = 1;		b->clicked = 1;		drawlevel();		sleep(500);		if(level.c.d == -1)			level.board[d][x][y].clicked = 0;		b->clicked = 0;		drawlevel();	}}voiddone(void){	level.done = 1;	draw(screen, screen->r, selected, gameover, ZP);	draw(screen, screen->r, selected, gameover, ZP);	flushimage(display, 1);}voidclicked(Point coord){	Point p;	int d;	/* ugly on purpose */	for(d = Depth - 1; d >= 0; d--) {		p = Pt((coord.x + TileDxy*d)/(Facex/2), (coord.y + TileDxy*d)/(Facey/2));		switch(level.board[d][p.x][p.y].which) {		case 0:			break;		case 1:			goto Found;		case 2:			p = Pt(p.x-1, p.y);			goto Found;		case 3:			p = Pt(p.x-1, p.y-1);			goto Found;		case 4:			p = Pt(p.x, p.y-1);			goto Found;		}	}	return;Found:	if(freeup(d, p) && (freeleft(d, p) || freeright(d, p))) {		if(level.c.d == -1) {			level.c.d = d;			level.c.p = p;			level.board[d][p.x][p.y].clicked = 1;		} else if(!eqpt(p, level.c.p) && 			(level.board[d][p.x][p.y].type == level.board[level.c.d][level.c.p.x][level.c.p.y].type)) {			clearbrick(d, p);			clearbrick(level.c.d, level.c.p);			level.c.d = -1;			level.c.p = Pt(0, 0);			level.remaining -= 2;		} else {			level.board[d][p.x][p.y].clicked = 0;			level.board[level.c.d][level.c.p.x][level.c.p.y].clicked = 0;			level.c.d = -1;			level.c.p = Pt(0, 0);		} 		drawlevel();		if(!canmove())			done();	}}voidlight(Point coord){	Point p;	int d;	/* ugly on purpose */	for(d = Depth - 1; d >= 0; d--) {		p = Pt((coord.x + TileDxy*d)/(Facex/2), (coord.y + TileDxy*d)/(Facey/2));		switch(level.board[d][p.x][p.y].which) {		case 0:			break;		case 1:			goto Found;		case 2:			p = Pt(p.x-1, p.y);			goto Found;		case 3:			p = Pt(p.x-1, p.y-1);			goto Found;		case 4:			p = Pt(p.x, p.y-1);			goto Found;		}	}	return;Found:	if(level.l.d == d && eqpt(level.l.p, p))		return;	if(freeup(d, p) && (freeleft(d, p) || freeright(d, p))) {		Point tmpp;		int tmpd;		tmpd = level.l.d;		tmpp = level.l.p;		level.l.d = d;		level.l.p = p;		drawbrick(d, p.x, p.y);		/* clean up the previously lit brick */		if(tmpd != -1 && level.board[tmpd][tmpp.x][tmpp.y].which == 1) 			drawbrick(tmpd, tmpp.x, tmpp.y);					draw(screen, screen->r, img, nil, ZP);		flushimage(display, 1);	} else if(level.l.d != -1) {		d = level.l.d;		p = level.l.p;		level.l.d = -1;		level.l.p = Pt(0, 0);		if(level.board[d][p.x][p.y].which == 1) {			drawbrick(d, p.x, p.y);			draw(screen, screen->r, img, nil, ZP);			flushimage(display, 1);		}	}}/* below only for testing */Pointpmatch(int d, Point p){	int x, y;	int ld = d;	do {		for(y = 0; y < Ly; y++)			for(x = 0; x < Lx; x++)				if(level.board[ld][x][y].which == 1 && isfree(ld, Pt(x, y)) && !eqpt(Pt(x, y), p) && 					level.board[d][p.x][p.y].type == level.board[ld][x][y].type)								return Pt(x, y);	} while(--ld >= 0);	return Pt(-1, -1);}intdmatch(int d, Point p){	int x, y;	int ld = d;	do {		for(y = 0; y < Ly; y++)			for(x = 0; x < Lx; x++)				if(level.board[ld][x][y].which == 1 && isfree(ld, Pt(x, y)) && !eqpt(Pt(x, y), p) && 					level.board[d][p.x][p.y].type == level.board[ld][x][y].type)								return ld;	} while(--ld >= 0);	return -1;}voidclearlevel(void){	int d, x, y;	for(d = Depth - 1; d >= 0; d--) 		for(y = 0; y < Ly; y++) 			for(x = 0; x < Lx; x++) 				if(level.board[d][x][y].which == 1 && isfree(d, Pt(x, y)))					if(bmatch(d, Pt(x, y)) != nil) {						clearbrick(dmatch(d, Pt(x, y)), pmatch(d, Pt(x, y)));						clearbrick(d, Pt(x, y));						level.remaining -= 2;						drawlevel();						clearlevel();					}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -