Plan 9 from Bell Labs’s /usr/web/sources/contrib/axel/rushhour/src/graphics.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>

#include "rushhour.h"

void
drawscreen(void)
{
	draw(screen, screen->r, img, nil, ZP);
	flushimage(display, 1);
}

void
drawwin(Point off)
{
	Rectangle r;
	Point p;

	p = level.win;
	p.x -= Off;
	p.x *= BoardX;
	p.y -= Off;
	p.y *= BoardY;
	p = addpt(p, off);
	p = addpt(p, Pt(1, 1));

	r = Rpt(p, Pt(p.x + BoardX, p.y+BoardY));
	draw(img, r, text, win, ZP);
}

void
drawboard(Point p, int *seen, Point off)
{
	Rectangle singletile, wholecar, t;
	Point tile, s, e;
	int o, i, l, w;
	uint square;

	square = item(p);
	p.x -= Off;
	p.x *= BoardX;
	p.y -= Off;
	p.y *= BoardY;

	w = OutlineWidth; /* width of colored outline for faces */

	/* leave some room from the edge of the window */
	p = addpt(p, Pt(1, 1));

	singletile = Rpt(p, addpt(p, Pt(BoardX, BoardY)));

	if (isvehicle(square)) {
		o = level.orient[square];
		l = level.length[square];
		if (o == OHoriz) {
			wholecar = Rpt(p, addpt(p, Pt(l*BoardX, BoardY)));
			tile = Pt(BoardX, 0);
		} else {
			wholecar = Rpt(p, addpt(p, Pt(BoardX, l*BoardY)));
			tile = Pt(0, BoardY);
		}
		if (seen) {
			if(seen[square])
					return;
				seen[square] = 1;
			}
		if (usefaces) {
			t = singletile;
			for (i=0; i < l; i++) {
				draw(img, t, bg, nil, ZP);
				t = rectaddpt(t, tile);
			}
			t = rectaddpt(singletile,off);
			for (i=0; i < l; i++) {
				draw(img, t, col[square], nil, ZP);
				draw(img, t, face[square], face[square], ZP);
				t = rectaddpt(t, tile);
			}
			/* draw colored outline */
			t = rectaddpt(wholecar,off);
			s = addpt(t.min, Pt(0, w));
			e = addpt(t.max, Pt(0, -w-1));
			line(img, s, Pt(e.x, s.y), Endsquare, Endsquare, w, col[square], ZP);
			line(img, e, Pt(s.x, e.y), Endsquare, Endsquare, w, col[square], ZP);
			s = addpt(t.min, Pt(w, 0));
			e = addpt(t.max, Pt(-w-1, 0));
			line(img, s, Pt(s.x, e.y), Endsquare, Endsquare, w, col[square], ZP);
			line(img, e, Pt(e.x, s.y), Endsquare, Endsquare, w, col[square], ZP);
			if (boutflag) { /* draw black outline on top, not sure whether I like it or not */
				s = t.min;
				e = addpt(t.max, Pt(0, -1));
				line(img, s, Pt(e.x, s.y), Endsquare, Endsquare, 0, black, ZP);
				line(img, e, Pt(s.x, e.y), Endsquare, Endsquare, 0, black, ZP);
				s = t.min;
				e = addpt(t.max, Pt(-1, 0));
				line(img, s, Pt(s.x, e.y), Endsquare, Endsquare, 0, black, ZP);
				line(img, e, Pt(e.x, s.y), Endsquare, Endsquare, 0, black, ZP);
			}
		} else {
			t = singletile;
			for (i=0; i < l; i++) {
				draw(img, t, empty, nil, ZP);
				t = rectaddpt(t, tile);
			}
			t = rectaddpt(wholecar,off);
			draw(img, t, car[square][o], msk[square][o], ZP);
		}
	} else {
		t = singletile;
		switch(square) {
		case Background:
			draw(img, t, bg, nil, ZP);
			break;
		case Empty:
			if (usefaces)
				draw(img, t, bg, nil, ZP);
			else
				draw(img, t, empty, nil, ZP);
			break;
		case Wall:
			if (usefaces)
				draw(img, t, face[square], nil, ZP);
			else
				draw(img, t, wall, nil, ZP);
			break;
		}
	}
}

void
resize(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*BoardX+10, p.y*BoardY+10);
		close(fd);
	}
}

Point
boardsize(Point p)
{
	return Pt(p.x*BoardX+2, p.y*BoardY+2);
}

void
drawlevel(void)
{
	int x, y;
	int seen[NElems];

	resize(subpt(level.max,Pt(Off,Off)));

	if(img)
		freeimage(img);
	img = eallocimage(Rpt(ZP, boardsize(subpt(level.max,Pt(Off,Off)))), 0, 0);	

	draw(img, insetrect(img->r, 1), empty, nil, ZP);

	memset(seen, 0, sizeof(int)*NElems);

	for(x = 0; x < MazeX; x++) {
		for(y = 0; y < MazeY; y++) {
			drawboard(Pt(x, y), seen, Pt(0,0));
		}
	}
}

int
intile(Point off, Point dir)
{
	if (dir.x > 0 && off.x >= 0 && off.x < BoardX)
		return 1;
	if (dir.x < 0 && off.x <= 0 && off.x > -BoardX)
		return 1;
	if (dir.y > 0 && off.y >= 0 && off.y < BoardY)
		return 1;
	if (dir.y < 0 && off.y <= 0 && off.y > -BoardY)
		return 1;
	return 0;
}

int
inhalftile(Point off, Point dir)
{
	if (dir.x > 0 && off.x >= 0 && off.x < BoardX/2.0)
		return 1;
	if (dir.x < 0 && off.x <= 0 && off.x > -BoardX/2.0)
		return 1;
	if (dir.y > 0 && off.y >= 0 && off.y < BoardY/2.0)
		return 1;
	if (dir.y < 0 && off.y <= 0 && off.y > -BoardY/2.0)
		return 1;
	return 0;
}

Point
subtile(Point p, Point dir)
{
	if (dir.x != 0)
		p.x -= dir.x * BoardX;
	else if (dir.y != 0)
		p.y -= dir.y * BoardY;
	return p;
}

Point
addtile(Point p, Point dir)
{
	if (dir.x != 0)
		p.x += dir.x * BoardX;
	else if (dir.y != 0)
		p.y += dir.y * BoardY;
	return p;
}

Point
getdir(Point p, Point off)
{
	int b, o;

	b = item(p);
	if (isvehicle(b)) {
		o = level.orient[b];
		if (o == OHoriz && off.x > 0)
			return Pt(1,0);
		else if (o == OHoriz && off.x < 0)
			return Pt(-1,0);
		else if (o == OVert && off.y > 0)
			return Pt(0,1);
		else if (o == OVert && off.y < 0)
			return Pt(0,-1);
	}
	return ZP;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.