123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- #include <u.h>
- #include <libc.h>
- #include <draw.h>
- #include <event.h>
- #include "mahjongg.h"
- /*
- * mark tiles that partially obscure the given tile.
- * relies on Depth*Dxy <= Tilex/2
- */
- void
- markabove(int d, int x, int y)
- {
- int dx, dy;
- for(d++; d < Depth; d++)
- for(dx = -1; dx <= 2; dx++)
- for(dy = -1; dy <= 2; dy++)
- if(x+dx < Lx && x+dx >= 0 &&
- y+dy < Ly && y+dy >= 0)
- level.board[d][x+dx][y+dy].redraw = 1;
- }
- void
- markbelow(int d, int x, int y)
- {
- int dx, dy;
- for(d--; d >= 0; d--)
- for(dx = -2; dx <= 1; dx++)
- for(dy = -2; dy <= 1; dy++)
- if(x+dx < Lx && x+dx >= 0 &&
- y+dy < Ly && y+dy >= 0)
- level.board[d][x+dx][y+dy].redraw = 1;
- }
- Rectangle
- tilerect(Click c)
- {
- Point p;
- Rectangle r;
- p = Pt(c.x*(Facex/2)-(c.d*TileDxy), c.y*(Facey/2)-(c.d*TileDxy));
- r = Rpt(p, addpt(p, Pt(Facex, Facey)));
- return rectaddpt(r, Pt(Depth*TileDxy, Depth*TileDxy));
- }
- void
- clearbrick(Click c)
- {
- Rectangle r;
- level.hist[--level.remaining] = c;
- level.board[c.d][c.x][c.y].which = None;
- level.board[c.d][c.x+1][c.y].which = None;
- level.board[c.d][c.x][c.y+1].which = None;
- level.board[c.d][c.x+1][c.y+1].which = None;
- r = tilerect(c);
- draw(img, r, background, nil, r.min);
- markabove(c.d, c.x, c.y);
- markbelow(c.d, c.x, c.y);
- }
- void
- drawbrick(Click c)
- {
- Rectangle r;
- r = tilerect(c);
- draw(img, r, tileset, nil, level.board[c.d][c.x][c.y].start);
- if(level.board[c.d][c.x][c.y].clicked)
- draw(img, r, selected, nil, ZP);
- if(eqcl(level.l, c))
- border(img, r, 2, litbrdr, level.board[c.d][c.x][c.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);
- }
- void
- redrawlevel(int all)
- {
- Brick *b;
- int d, x, y;
- for(d = 0; d < Depth; d++)
- for(y = 0; y < Ly; y++)
- for(x = 0; x < Lx; x++) {
- b = &level.board[d][x][y];
- if(b->which == TL && (all || b->redraw)) {
- drawbrick(Cl(d,x,y));
- markabove(d,x,y);
- }
- b->redraw = 0;
- }
- draw(screen, screen->r, img, nil, ZP);
- flushimage(display, 1);
- }
- void
- updatelevel(void)
- {
- redrawlevel(0);
- }
- void
- drawlevel(void)
- {
- draw(img, img->r, background, nil, ZP);
- redrawlevel(1);
- }
- void
- resize(Point p)
- {
- int fd;
- fd = open("/dev/wctl", OWRITE);
- if(fd >= 0){
- fprint(fd, "resize -dx %d -dy %d", p.x, p.y);
- close(fd);
- }
- }
- void
- hint(void)
- {
- int d = 0, x = 0, y = 0;
- Brick *b = nil;
- if(level.c.d != -1) {
- if((b = bmatch(level.c)) != nil) {
- d = level.c.d;
- x = level.c.x;
- y = level.c.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 == TL &&
- isfree(Cl(d,x,y)) &&
- (b = bmatch(Cl(d,x,y))) != nil)
- goto Matched;
- Matched:
- if (b == nil)
- return;
- level.board[d][x][y].clicked = 1;
- b->clicked = 1;
- b->redraw = 1;
- updatelevel();
- sleep(500);
- if(level.c.d == -1)
- level.board[d][x][y].clicked = 0;
- b->clicked = 0;
- b->redraw = 1;
- updatelevel();
- sleep(500);
- level.board[d][x][y].clicked = 1;
- b->clicked = 1;
- b->redraw = 1;
- updatelevel();
- sleep(500);
- if(level.c.d == -1)
- level.board[d][x][y].clicked = 0;
- b->clicked = 0;
- b->redraw = 1;
- updatelevel();
- }
- void
- done(void)
- {
- level.done = 1;
- draw(screen, screen->r, selected, gameover, ZP);
- draw(screen, screen->r, selected, gameover, ZP);
- flushimage(display, 1);
- }
- Click
- findclick(Point coord)
- {
- Click c;
- for(c.d = Depth - 1; c.d >= 0; c.d--) {
- c.x = (coord.x + TileDxy*c.d)/(Facex/2);
- c.y = (coord.y + TileDxy*c.d)/(Facey/2);
- switch(level.board[c.d][c.x][c.y].which) {
- case None:
- break;
- case TL:
- return c;
- case TR:
- c.x = c.x - 1;
- return c;
- case BR:
- c.x = c.x - 1;
- c.y = c.y - 1;
- return c;
- case BL:
- c.y = c.y - 1;
- return c;
- }
- }
- return NC;
- }
- void
- clicked(Point coord)
- {
- Click c;
- Brick *b, *bc;
- c = findclick(coord);
- if (c.d == -1)
- return;
- b = &level.board[c.d][c.x][c.y];
- if(isfree(c)) {
- if(level.c.d == -1) {
- level.c = c;
- b->clicked = 1;
- b->redraw = 1;
- } else if(eqcl(c, level.c)) {
- level.c = NC;
- b->clicked = 0;
- b->redraw = 1;
- } else {
- bc = &level.board[level.c.d][level.c.x][level.c.y];
- if(b->type == bc->type) {
- clearbrick(c);
- bc->clicked = 0;
- clearbrick(level.c);
- level.c = NC;
- } else {
- bc->clicked = 0;
- bc->redraw = 1;
- b->clicked = 1;
- b->redraw = 1;
- level.c = c;
- }
- }
- updatelevel();
- if(!canmove())
- done();
- }
- }
- void
- undo(void)
- {
- int i, j, d, x, y;
- if(level.remaining >= Tiles)
- return;
- for(i=1; i<=2; i++) {
- j = level.remaining++;
- d = level.hist[j].d;
- x = level.hist[j].x;
- y = level.hist[j].y;
- level.board[d][x][y].which = TL;
- level.board[d][x+1][y].which = TR;
- level.board[d][x+1][y+1].which = BR;
- level.board[d][x][y+1].which = BL;
- level.board[d][x][y].redraw = 1;
- }
- updatelevel();
- }
- void
- deselect(void)
- {
- Brick *b;
- if(level.c.d == -1)
- return;
- b = &level.board[level.c.d][level.c.x][level.c.y];
- level.c = NC;
- b->clicked = 0;
- b->redraw = 1;
- updatelevel();
- }
- void
- light(Point coord)
- {
- Click c = findclick(coord);
- if (c.d == -1)
- return;
- if(eqcl(level.l, c))
- return;
- if (level.l.d != -1) {
- level.board[level.l.d][level.l.x][level.l.y].redraw = 1;
- level.l = NC;
- }
- if(isfree(c)) {
- level.l = c;
- level.board[c.d][c.x][c.y].redraw = 1;
- }
- updatelevel();
- }
- void
- clearlevel(void)
- {
- Click c, cm;
- for(c.d = Depth - 1; c.d >= 0; c.d--)
- for(c.y = 0; c.y < Ly; c.y++)
- for(c.x = 0; c.x < Lx; c.x++)
- if(level.board[c.d][c.x][c.y].which == TL &&
- isfree(c)) {
- cm = cmatch(c, c.d);
- if(cm.d != -1) {
- clearbrick(cm);
- clearbrick(c);
- updatelevel();
- clearlevel();
- }
- }
- }
|