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

📄 xs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "xs.h"/* * engine for 4s, 5s, etc */Cursor whitearrow = {	{0, 0},	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC, 	 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8, 0xFF, 0xFC, 	 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC, 	 0xF3, 0xF8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, },	{0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0xC0, 0x1C, 	 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x38, 0xC0, 0x1C, 	 0xC0, 0x0E, 0xC0, 0x07, 0xCE, 0x0E, 0xDF, 0x1C, 	 0xD3, 0xB8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, }};enum{	CNone	= 0,	CBounds	= 1,	CPiece	= 2,	NX	= 10,	NY	= 20,};enum{	TIMER,	MOUSE,	RESHAPE,	KBD,	SUSPEND,	NALT};char		board[NY][NX];Rectangle	rboard;Point		pscore;Point		scoresz;int		pcsz = 32;Point		pos;Image	*bb, *bbmask, *bb2, *bb2mask;Image	*whitemask;Rectangle	br, br2;long		points;int		dt;int		DY;int		DMOUSE;int		lastmx;Mouse	mouse;int		newscreen;Channel	*timerc;Channel	*suspc;Channel	*mousec;Channel	*kbdc;Mousectl	*mousectl;Keyboardctl	*kbdctl;int		suspended;void		redraw(int);int	tsleep;Piece *piece;#define	NCOL	10uchar txbits[NCOL][32]={	{0xDD,0xDD,0xFF,0xFF,0x77,0x77,0xFF,0xFF,	 0xDD,0xDD,0xFF,0xFF,0x77,0x77,0xFF,0xFF,	 0xDD,0xDD,0xFF,0xFF,0x77,0x77,0xFF,0xFF,	 0xDD,0xDD,0xFF,0xFF,0x77,0x77,0xFF,0xFF},	{0xDD,0xDD,0x77,0x77,0xDD,0xDD,0x77,0x77,	 0xDD,0xDD,0x77,0x77,0xDD,0xDD,0x77,0x77,	 0xDD,0xDD,0x77,0x77,0xDD,0xDD,0x77,0x77,	 0xDD,0xDD,0x77,0x77,0xDD,0xDD,0x77,0x77},	{0xAA,0xAA,0x55,0x55,0xAA,0xAA,0x55,0x55,	 0xAA,0xAA,0x55,0x55,0xAA,0xAA,0x55,0x55,	 0xAA,0xAA,0x55,0x55,0xAA,0xAA,0x55,0x55,	 0xAA,0xAA,0x55,0x55,0xAA,0xAA,0x55,0x55},	{0xAA,0xAA,0x55,0x55,0xAA,0xAA,0x55,0x55,	 0xAA,0xAA,0x55,0x55,0xAA,0xAA,0x55,0x55,	 0xAA,0xAA,0x55,0x55,0xAA,0xAA,0x55,0x55,	 0xAA,0xAA,0x55,0x55,0xAA,0xAA,0x55,0x55},	{0x22,0x22,0x88,0x88,0x22,0x22,0x88,0x88,	 0x22,0x22,0x88,0x88,0x22,0x22,0x88,0x88,	 0x22,0x22,0x88,0x88,0x22,0x22,0x88,0x88,	 0x22,0x22,0x88,0x88,0x22,0x22,0x88,0x88},	{0x22,0x22,0x00,0x00,0x88,0x88,0x00,0x00,	 0x22,0x22,0x00,0x00,0x88,0x88,0x00,0x00,	 0x22,0x22,0x00,0x00,0x88,0x88,0x00,0x00,	 0x22,0x22,0x00,0x00,0x88,0x88,0x00,0x00},	{0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,	 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,	 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,	 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00},	{0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,	 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,	 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,	 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00},	{0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,	 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,	 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,	 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC},	{0xCC,0xCC,0xCC,0xCC,0x33,0x33,0x33,0x33,	 0xCC,0xCC,0xCC,0xCC,0x33,0x33,0x33,0x33,	 0xCC,0xCC,0xCC,0xCC,0x33,0x33,0x33,0x33,	 0xCC,0xCC,0xCC,0xCC,0x33,0x33,0x33,0x33},};int txpix[NCOL] = {	DYellow,	/* yellow */	DCyan,	/* cyan */	DGreen,	/* lime green */	DGreyblue,	/* slate */	DRed,	/* red */	DGreygreen,	/* olive green */	DBlue,	/* blue */	0xFF55AAFF,	/* pink */	0xFFAAFFFF,	/* lavender */	0xBB005DFF,	/* maroon */};Image *tx[NCOL];intmovemouse(void){	mouse.xy = Pt(rboard.min.x + Dx(rboard)/2, rboard.min.y +Dy(rboard)/2);	moveto(mousectl, mouse.xy);	return mouse.xy.x;}intwarp(Point p, int x){	if (!suspended && piece != nil) {		x = pos.x + piece->sz.x*pcsz/2;		if (p.y < rboard.min.y)			p.y = rboard.min.y;		if (p.y >= rboard.max.y)			p.y = rboard.max.y - 1;		moveto(mousectl, Pt(x, p.y));	}	return x;}Piece *rotr(Piece *p){	if(p->rot == 3)		return p-3;	return p+1;}Piece *rotl(Piece *p){	if(p->rot == 0)		return p+3;	return p-1;}intcollide(Point pt, Piece *p){	int i;	int c = CNone;	pt.x = (pt.x - rboard.min.x) / pcsz;	pt.y = (pt.y - rboard.min.y) / pcsz;	for(i=0; i<N; i++){		pt.x += p->d[i].x;		pt.y += p->d[i].y;		if(pt.x<0 || pt.x>=NX || pt.y<0 || pt.y>=NY)			c |= CBounds;		if(board[pt.y][pt.x])			c |= CPiece;	}	return c;}intcollider(Point pt, Point pmax){	int i, j, pi, pj, n, m;	pi = (pt.x - rboard.min.x) / pcsz;	pj = (pt.y - rboard.min.y) / pcsz;	n = pmax.x / pcsz;	m = pmax.y / pcsz + 1;	for(i = pi; i < pi+n && i < NX; i++)		for(j = pj; j < pj+m && j < NY; j++)			if(board[j][i])				return 1;	return 0;}voidsetpiece(Piece *p){	int i;	Rectangle r, r2;	Point op, delta;	draw(bb, bb->r, display->white, nil, ZP);	draw(bbmask, bbmask->r, display->transparent, nil, ZP);	br = Rect(0, 0, 0, 0);	br2 = br;	piece = p;	if(p == 0)		return;	r.min = bb->r.min;	for(i=0; i<N; i++){		r.min.x += p->d[i].x*pcsz;		r.min.y += p->d[i].y*pcsz;		r.max.x = r.min.x + pcsz;		r.max.y = r.min.y + pcsz;		if(i == 0){			draw(bb, r, display->black, nil, ZP);			draw(bb, insetrect(r, 1), tx[piece->tx], nil, ZP);			draw(bbmask, r, display->opaque, nil, ZP);			op = r.min;		}else{			draw(bb, r, bb, nil, op);			draw(bbmask, r, bbmask, nil, op);		}		if(br.max.x < r.max.x)			br.max.x = r.max.x;		if(br.max.y < r.max.y)			br.max.y = r.max.y;	}	br.max = subpt(br.max, bb->r.min);	delta = Pt(0,DY);	br2.max = addpt(br.max, delta);	r = rectaddpt(br, bb2->r.min);	r2 = rectaddpt(br2, bb2->r.min);	draw(bb2, r2, display->white, nil, ZP);	draw(bb2, rectaddpt(r,delta), bb, nil, bb->r.min);	draw(bb2mask, r2, display->transparent, nil, ZP);	draw(bb2mask, r, display->opaque, bbmask, bb->r.min);	draw(bb2mask, rectaddpt(r,delta), display->opaque, bbmask, bb->r.min);}voiddrawpiece(void){	draw(screen, rectaddpt(br, pos), bb, bbmask, bb->r.min);	if (suspended)		draw(screen, rectaddpt(br, pos), display->white, whitemask, ZP);}voidundrawpiece(void){	Image *mask = nil;	if(collider(pos, br.max))		mask = bbmask;	draw(screen, rectaddpt(br, pos), display->white, mask, bb->r.min);}voidrest(void){	int i;	Point pt;	pt = divpt(subpt(pos, rboard.min), pcsz);	for(i=0; i<N; i++){		pt.x += piece->d[i].x;		pt.y += piece->d[i].y;		board[pt.y][pt.x] = piece->tx+16;	}}intcanfit(Piece *p){	static int dx[]={0, -1, 1, -2, 2, -3, 3, 4, -4};	int i, j;	Point z;	j = N + 1;	if(j >= 4){		j = p->sz.x;		if(j<p->sz.y)			j = p->sz.y;		j = 2*j-1;	}	for(i=0; i<j; i++){		z.x = pos.x + dx[i]*pcsz;		z.y = pos.y;		if(!collide(z, p)){			z.y = pos.y + pcsz-1;			if(!collide(z, p)){				undrawpiece();				pos.x = z.x;				return 1;			}		}	}	return 0;}voidscore(int p){	char buf[128];	points += p;	snprint(buf, sizeof(buf), "%.6ld", points);	draw(screen, Rpt(pscore, addpt(pscore, scoresz)), display->white, nil, ZP);	string(screen, pscore, display->black, ZP, font, buf);}voiddrawsq(Image *b, Point p, int ptx){	Rectangle r;	r.min = p;	r.max.x = r.min.x+pcsz;	r.max.y = r.min.y+pcsz;	draw(b, r, display->black, nil, ZP);	draw(b, insetrect(r, 1), tx[ptx], nil, ZP);}voiddrawboard(void){	int i, j;	border(screen, insetrect(rboard, -2), 2, display->black, ZP);	draw(screen, Rect(rboard.min.x, rboard.min.y-2, rboard.max.x, rboard.min.y),		display->white, nil, ZP);	for(i=0; i<NY; i++)		for(j=0; j<NX; j++)			if(board[i][j])				drawsq(screen, Pt(rboard.min.x+j*pcsz, rboard.min.y+i*pcsz), board[i][j]-16);	score(0);	if (suspended)		draw(screen, screen->r, display->white, whitemask, ZP);}voidchoosepiece(void){	int i;	do{		i = nrand(NP);		setpiece(&pieces[i]);		pos = rboard.min;		pos.x += nrand(NX)*pcsz;	}while(collide(Pt(pos.x, pos.y+pcsz-DY), piece));	drawpiece();	flushimage(display, 1);}intmovepiece(void){	Image *mask = nil;	if(collide(Pt(pos.x, pos.y+pcsz), piece))		return 0;	if(collider(pos, br2.max))		mask = bb2mask;	draw(screen, rectaddpt(br2, pos), bb2, mask, bb2->r.min);	pos.y += DY;	flushimage(display, 1);	return 1;}voidsuspend(int s){	suspended = s;	if (suspended)		setcursor(mousectl, &whitearrow);	else		setcursor(mousectl, nil);	if (!suspended)		drawpiece();	drawboard();	flushimage(display, 1);}voidpause(int t){	int s;	Alt alts[NALT+1];	alts[TIMER].c = timerc;	alts[TIMER].v = nil;	alts[TIMER].op = CHANRCV;	alts[SUSPEND].c = suspc;	alts[SUSPEND].v = &s;	alts[SUSPEND].op = CHANRCV;	alts[RESHAPE].c = mousectl->resizec;	alts[RESHAPE].v = nil;	alts[RESHAPE].op = CHANRCV;	// avoid hanging up those writing ong mousec and kbdc	// so just accept it all and keep mouse up-to-date	alts[MOUSE].c = mousec;	alts[MOUSE].v = &mouse;	alts[MOUSE].op = CHANRCV;	alts[KBD].c = kbdc;	alts[KBD].v = nil;	alts[KBD].op = CHANRCV;	alts[NALT].op = CHANEND;	flushimage(display, 1);	for(;;)		switch(alt(alts)){		case SUSPEND:			if (!suspended && s) {				suspend(1);			} else if (suspended && !s) {				suspend(0);				lastmx = warp(mouse.xy, lastmx);			}			break;		case TIMER:			if(suspended)				break;			if((t -= tsleep) < 0)				return;			break;		case RESHAPE:			redraw(1);			break;				}}inthoriz(void){	int lev[MAXN];	int i, j, h;	Rectangle r;	h = 0;	for(i=0; i<NY; i++){		for(j=0; board[i][j]; j++)			if(j == NX-1){				lev[h++] = i;				break;

⌨️ 快捷键说明

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