#include #include #include #include #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; }