Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <draw.h>
4
#include <event.h>
5
 
6
#include "mahjongg.h"
7
 
8
 
9
/*
10
 * mark tiles that partially obscure the given tile.
11
 * relies on Depth*Dxy <= Tilex/2
12
 */
13
void
14
markabove(int d, int x, int y)
15
{
16
	int dx, dy;
17
 
18
	for(d++; d < Depth; d++)
19
		for(dx = -1; dx <= 2; dx++)
20
			for(dy = -1; dy <= 2; dy++)
21
				if(x+dx < Lx && x+dx >= 0 &&
22
				    y+dy < Ly && y+dy >= 0)
23
					level.board[d][x+dx][y+dy].redraw = 1;
24
}
25
 
26
void
27
markbelow(int d, int x, int y)
28
{
29
	int dx, dy;
30
 
31
	for(d--; d >= 0; d--)
32
		for(dx = -2; dx <= 1; dx++)
33
			for(dy = -2; dy <= 1; dy++)
34
				if(x+dx < Lx && x+dx >= 0 &&
35
				    y+dy < Ly && y+dy >= 0)
36
					level.board[d][x+dx][y+dy].redraw = 1;
37
}
38
 
39
Rectangle
40
tilerect(Click c)
41
{
42
	Point p;
43
	Rectangle r;
44
 
45
	p = Pt(c.x*(Facex/2)-(c.d*TileDxy), c.y*(Facey/2)-(c.d*TileDxy));
46
	r = Rpt(p, addpt(p, Pt(Facex, Facey)));
47
	return rectaddpt(r, Pt(Depth*TileDxy, Depth*TileDxy));
48
}
49
 
50
void
51
clearbrick(Click c)
52
{
53
	Rectangle r;
54
 
55
	level.hist[--level.remaining] = c;
56
 
57
	level.board[c.d][c.x][c.y].which = None;
58
	level.board[c.d][c.x+1][c.y].which = None;
59
	level.board[c.d][c.x][c.y+1].which = None;
60
	level.board[c.d][c.x+1][c.y+1].which = None;
61
 
62
	r = tilerect(c);
63
	draw(img, r, background, nil, r.min);
64
 
65
	markabove(c.d, c.x, c.y);
66
	markbelow(c.d, c.x, c.y);
67
}
68
 
69
void
70
drawbrick(Click c)
71
{
72
	Rectangle r;
73
 
74
	r = tilerect(c);
75
	draw(img, r, tileset, nil, level.board[c.d][c.x][c.y].start);
76
 
77
	if(level.board[c.d][c.x][c.y].clicked)
78
		draw(img, r, selected, nil, ZP);
79
 
80
	if(eqcl(level.l, c))
81
		border(img, r, 2, litbrdr, level.board[c.d][c.x][c.y].start);
82
 
83
	/* looks better without borders, uncomment to check it out with'em */
84
//	r = Rpt(r.min, addpt(r.min, Pt(Tilex, Tiley)));
85
//	draw(img, r, brdr, nil, ZP);
86
}
87
 
88
void
89
redrawlevel(int all)
90
{
91
	Brick *b;
92
	int d, x, y;
93
 
94
	for(d = 0; d < Depth; d++)
95
		for(y = 0; y < Ly; y++)
96
			for(x = 0; x < Lx; x++) {
97
				b = &level.board[d][x][y];
98
				if(b->which == TL && (all || b->redraw)) {
99
					drawbrick(Cl(d,x,y));
100
					markabove(d,x,y);
101
				}
102
				b->redraw = 0;
103
			}
104
 
105
	draw(screen, screen->r, img, nil, ZP);
106
	flushimage(display, 1);
107
}
108
 
109
void
110
updatelevel(void)
111
{
112
	redrawlevel(0);
113
}
114
 
115
void
116
drawlevel(void)
117
{
118
	draw(img, img->r, background, nil, ZP);
119
	redrawlevel(1);
120
}
121
 
122
void
123
resize(Point p)
124
{
125
	int fd;
126
 
127
	fd = open("/dev/wctl", OWRITE);
128
	if(fd >= 0){
129
		fprint(fd, "resize -dx %d -dy %d", p.x, p.y);
130
		close(fd);
131
	}
132
}
133
 
134
void
135
hint(void)
136
{
137
	int d = 0, x = 0, y = 0;
138
	Brick *b = nil;
139
 
140
	if(level.c.d != -1) {
141
		if((b = bmatch(level.c)) != nil) {
142
			d = level.c.d;
143
			x = level.c.x;
144
			y = level.c.y;
145
		}
146
	} else 
147
		for(d = Depth - 1; d >= 0; d--)
148
			for(y = 0; y < Ly; y++)
149
				for(x = 0; x < Lx; x++)
150
					if(level.board[d][x][y].which == TL &&
151
					    isfree(Cl(d,x,y)) &&
152
					    (b = bmatch(Cl(d,x,y))) != nil)
153
						goto Matched;
154
Matched:
155
	if (b == nil)
156
		return;
157
	level.board[d][x][y].clicked = 1;
158
	b->clicked = 1;
159
	b->redraw = 1;
160
	updatelevel();
161
	sleep(500);
162
	if(level.c.d == -1)
163
		level.board[d][x][y].clicked = 0;
164
	b->clicked = 0;
165
	b->redraw = 1;
166
	updatelevel();
167
	sleep(500);
168
	level.board[d][x][y].clicked = 1;
169
	b->clicked = 1;
170
	b->redraw = 1;
171
	updatelevel();
172
	sleep(500);
173
	if(level.c.d == -1)
174
		level.board[d][x][y].clicked = 0;
175
	b->clicked = 0;
176
	b->redraw = 1;
177
	updatelevel();
178
}
179
 
180
void
181
done(void)
182
{
183
	level.done = 1;
184
	draw(screen, screen->r, selected, gameover, ZP);
185
	flushimage(display, 1);
186
}
187
 
188
Click
189
findclick(Point coord)
190
{
191
	Click c;
192
 
193
	for(c.d = Depth - 1; c.d >= 0; c.d--) {
194
		c.x = (coord.x + TileDxy*c.d)/(Facex/2);
195
		c.y = (coord.y + TileDxy*c.d)/(Facey/2);
196
		switch(level.board[c.d][c.x][c.y].which) {
197
		case None:
198
			break;
199
		case TL:
200
			return c;
201
		case TR:
202
			c.x = c.x - 1;
203
			return c;
204
		case BR:
205
			c.x = c.x - 1;
206
			c.y = c.y - 1;
207
			return c;
208
		case BL:
209
			c.y = c.y - 1;
210
			return c;
211
		}
212
	}
213
	return NC;
214
}
215
 
216
void
217
clicked(Point coord)
218
{
219
	Click c;
220
	Brick *b, *bc;
221
 
222
	c = findclick(coord);
223
	if (c.d == -1)
224
		return;
225
 
226
	b = &level.board[c.d][c.x][c.y];
227
	if(isfree(c)) {
228
		if(level.c.d == -1) {
229
			level.c = c;
230
			b->clicked = 1;
231
			b->redraw = 1;
232
		} else if(eqcl(c, level.c)) {
233
			level.c = NC;
234
			b->clicked = 0;
235
			b->redraw = 1;
236
		} else {
237
			bc = &level.board[level.c.d][level.c.x][level.c.y];
238
			if(b->type == bc->type) {
239
				clearbrick(c);
240
				bc->clicked = 0;
241
				clearbrick(level.c);
242
				level.c = NC;
243
			} else {
244
				bc->clicked = 0;
245
				bc->redraw = 1;
246
				b->clicked = 1;
247
				b->redraw = 1;
248
				level.c = c;
249
			}
250
		}
251
		updatelevel();
252
		if(!canmove())
253
			done();
254
	}
255
}
256
 
257
void
258
undo(void)
259
{
260
	int i, j, d, x, y;
261
 
262
	if(level.remaining >= Tiles)
263
		return;
264
 
265
	for(i=1; i<=2; i++) {
266
		j = level.remaining++;
267
		d = level.hist[j].d;
268
		x = level.hist[j].x;
269
		y = level.hist[j].y;
270
		level.board[d][x][y].which = TL;
271
		level.board[d][x+1][y].which = TR;
272
		level.board[d][x+1][y+1].which = BR;
273
		level.board[d][x][y+1].which = BL;
274
		level.board[d][x][y].redraw = 1;
275
	}
276
	updatelevel();
277
}
278
 
279
void
280
deselect(void)
281
{
282
	Brick *b;
283
 
284
	if(level.c.d == -1)
285
		return;
286
	b = &level.board[level.c.d][level.c.x][level.c.y];
287
	level.c = NC;
288
	b->clicked = 0;
289
	b->redraw = 1;
290
	updatelevel();
291
}
292
 
293
void
294
light(Point coord)
295
{
296
	Click c = findclick(coord);
297
	if (c.d == -1)
298
		return;
299
 
300
	if(eqcl(level.l, c))
301
		return;
302
 
303
	if (level.l.d != -1) {
304
		level.board[level.l.d][level.l.x][level.l.y].redraw = 1;
305
		level.l = NC;
306
	}
307
 
308
	if(isfree(c)) {
309
		level.l = c;
310
		level.board[c.d][c.x][c.y].redraw = 1;
311
	}
312
 
313
	updatelevel();
314
}
315
 
316
void
317
clearlevel(void)
318
{
319
	Click c, cm;
320
 
321
	for(c.d = Depth - 1; c.d >= 0; c.d--)
322
		for(c.y = 0; c.y < Ly; c.y++)
323
			for(c.x = 0; c.x < Lx; c.x++)
324
				if(level.board[c.d][c.x][c.y].which == TL &&
325
				    isfree(c)) {
326
					cm = cmatch(c, c.d);
327
					if(cm.d != -1) {
328
						clearbrick(cm);
329
						clearbrick(c);
330
						updatelevel();
331
						clearlevel();
332
					}
333
				}
334
}