7 int MaxX, MaxY, Mines, Level, UnknownCell, Playing, MinesRemain, Time, Status, UseQuery = TRUE, UseColor = TRUE;
11 Image *RGB000000, *RGB0000FF, *RGB007F00, *RGB7F7F7F, *RGBBFBFBF, *RGBFF0000, *RGBFFFF00, *RGBFFFFFF, *ImageButton[5], *ImageSign, *ImageDigit[10], *ImageCell[16];
13 FieldCell **MineField;
15 void Pack(Point *p, Point p0, Point p1, Point p2, Point p3, Point p4, Point p5) {
25 void Button3d(Image *im, Rectangle r, int i, Image *color1, Image *color2, Image *color3, Point sp) {
34 draw(im, Rect(r.min.x + i, r.min.y + i, r.max.x - i, r.max.y - i), color1, nil, Pt(sp.x + i, sp.y + i));
36 Pack(p, r.min, Pt(r.min.x, r.max.y), Pt(r.min.x + i, r.max.y - i), Pt(r.min.x + i, r.min.y + i), Pt(r.max.x - i, r.min.y + i), Pt(r.max.x, r.min.y));
37 fillpoly(im, p, 6, 0, color2, sp);
39 Pack(p, r.max, Pt(r.min.x, r.max.y), Pt(r.min.x + i, r.max.y - i), Pt(r.max.x - i, r.max.y - i), Pt(r.max.x - i, r.min.y + i), Pt(r.max.x, r.min.y));
40 fillpoly(im, p, 6, 0, color3, sp);
43 void DisplayCounter(int x, int n) {
47 Button3d(screen, Rect(x, Origin.y + 16, x + 41, Origin.y + 41), 1, RGB000000, RGB7F7F7F, RGBFFFFFF, ZP);
52 A = ImageDigit[abs(n / 100 - n / 1000 * 10)];
53 B = ImageDigit[abs(n / 10 - n / 100 * 10)];
54 C = ImageDigit[abs(n / 1 - n / 10 * 10)];
56 if(n < 0) A = ImageSign;
58 draw(screen, Rect(x + 2, Origin.y + 18, x + 13, Origin.y + 39), A, nil, ZP);
59 draw(screen, Rect(x + 15, Origin.y + 18, x + 26, Origin.y + 39), B, nil, ZP);
60 draw(screen, Rect(x + 28, Origin.y + 18, x + 39, Origin.y + 39), C, nil, ZP);
63 void DrawButton(int Index) {
65 draw(screen, Rect(Origin.x + MaxX * 8 - 1, Origin.y + 16, Origin.x + MaxX * 8 + 24, Origin.y + 41), ImageButton[Index], nil, ZP);
68 void DrawCell(Point Cell) {
70 draw(screen, Rect(Origin.x + 12 + Cell.x * 16, Origin.y + 57 + Cell.y * 16, Origin.x + 12 + Cell.x * 16 + Dx(ImageCell[MineField[Cell.x][Cell.y].Picture]->r), Origin.y + 57 + Cell.y * 16 + Dy(ImageCell[MineField[Cell.x][Cell.y].Picture]->r)), ImageCell[MineField[Cell.x][Cell.y].Picture], nil, ZP);
73 void eresized(int New) {
75 if(New && getwindow(display, Refmesg) < 0)
76 fprint(2,"%s: can't reattach to window", argv0);
78 Origin.x = screen->r.min.x + (screen->r.max.x - screen->r.min.x - 23 - MaxX * 16) / 2;
79 Origin.y = screen->r.min.y + (screen->r.max.y - screen->r.min.y - 68 - MaxY * 16) / 2;
81 draw(screen, screen->r, RGB0000FF, nil, ZP);
84 Button3d(screen, Rect(Origin.x, Origin.y, Origin.x + 23 + MaxX * 16, Origin.y + 68 + MaxY * 16), 3, RGBBFBFBF, RGBFFFFFF, RGB7F7F7F, ZP);
86 /* top small window with button and 2 counters */
87 Button3d(screen, Rect(Origin.x + 9, Origin.y + 9, Origin.x + 14 + MaxX * 16, Origin.y + 48), 2, RGBBFBFBF, RGB7F7F7F, RGBFFFFFF, ZP);
92 /* counter on the left side - remaining mines */
93 DisplayCounter(Origin.x + 16, MinesRemain);
95 /* counter on the right side - timer */
96 DisplayCounter(Origin.x -34 + MaxX * 16, Time);
98 /* bottom window - mine field */
99 Button3d(screen, Rect(Origin.x + 9, Origin.y + 54, Origin.x + 14 + MaxX * 16, Origin.y + 59 + MaxY * 16), 3, RGBBFBFBF, RGB7F7F7F, RGBFFFFFF, ZP);
104 for(x = 1; x < MaxX; x++)
105 line(screen, Pt(Origin.x + 11 + x * 16, Origin.y + 57), Pt(Origin.x + 11 + x * 16, Origin.y + 55 + MaxY * 16), Endsquare, Endsquare, 0, RGB7F7F7F, ZP);
107 for(y = 1; y < MaxY; y++)
108 line(screen, Pt(Origin.x + 12, Origin.y + 56 + y * 16), Pt(Origin.x + 10 + MaxX * 16, Origin.y + 56 + y * 16), Endsquare, Endsquare, 0, RGB7F7F7F, ZP);
110 for(y = 0; y < MaxY; y++)
111 for(x = 0; x < MaxX; x++)
116 void MouseCell(Point Cell) {
120 switch(MineField[Cell.x][Cell.y].Picture) {
125 Picture = MouseQuery;
130 draw(screen, Rect(Origin.x + 12 + Cell.x * 16, Origin.y + 57 + Cell.y * 16, Origin.x + 12 + Cell.x * 16 + Dx(ImageCell[Picture]->r), Origin.y + 57 + Cell.y * 16 + Dy(ImageCell[Picture]->r)), ImageCell[Picture], nil, ZP);
133 void RecoverCell(Point Cell) {
135 switch(MineField[Cell.x][Cell.y].Picture) {
138 draw(screen, Rect(Origin.x + 12 + Cell.x * 16, Origin.y + 57 + Cell.y * 16, Origin.x + 12 + Cell.x * 16 + Dx(ImageCell[MineField[Cell.x][Cell.y].Picture]->r), Origin.y + 57 + Cell.y * 16 + Dy(ImageCell[MineField[Cell.x][Cell.y].Picture]->r)), ImageCell[MineField[Cell.x][Cell.y].Picture], nil, ZP);
142 void *emalloc(ulong size) {
148 fprint(2, "%s: no memory: %r\n", argv0);
154 void InitMineField(void) {
156 /* clean up mine field, make all cells unknown and place new mines */
160 for(y = 0; y < MaxY; y++)
161 for(x = 0; x < MaxX; x++) {
162 MineField[x][y].Mine = FALSE;
163 MineField[x][y].Picture = Unknown;
166 for(i = 0; i < Mines; ) {
169 if(MineField[x][y].Mine) continue;
170 MineField[x][y].Mine = TRUE;
175 /* count mines in neighbourhood */
179 for(y = 0; y < MaxY; y++)
180 for(x = 0; x < MaxX; x++) {
181 MineField[x][y].Neighbours = 0;
182 if(x > 0 && MineField[x - 1][y].Mine) MineField[x][y].Neighbours++;
183 if(y > 0 && MineField[x][y - 1].Mine) MineField[x][y].Neighbours++;
184 if(x < MaxX -1 && MineField[x + 1][y].Mine) MineField[x][y].Neighbours++;
185 if(y < MaxY - 1 && MineField[x][y + 1].Mine) MineField[x][y].Neighbours++;
186 if(x > 0 && y > 0 && MineField[x - 1][y - 1].Mine) MineField[x][y].Neighbours++;
187 if(x > 0 && y < MaxY - 1 && MineField[x - 1][y + 1].Mine) MineField[x][y].Neighbours++;
188 if(x < MaxX - 1 && y > 0 && MineField[x + 1][y - 1].Mine) MineField[x][y].Neighbours++;
189 if(x < MaxX - 1 && y < MaxY - 1 && MineField[x + 1][y + 1].Mine) MineField[x][y].Neighbours++;
197 UnknownCell = MaxX * MaxY - Mines;
200 void NewMineField(int NewLevel) {
202 int CurrentMaxX, CurrentMaxY;
209 /* set size of mine field and number of mines */
210 if(Level == Custom) {
212 /* here should ask a player about custom size of mine field and number of mines; in next release, may be... */
214 if(MaxX < 8) MaxX = 8;
215 if(MaxY < 8) MaxY = 8;
216 if(Mines < 10) Mines = 10;
217 if(MaxX > 30) MaxX = 30;
218 if(MaxY > 24) MaxY = 24;
219 if(Mines > (MaxX - 1) * (MaxY - 1)) Mines = (MaxX - 1) * (MaxY - 1);
222 MaxX = Settings[Level].MaxX;
223 MaxY = Settings[Level].MaxY;
224 Mines = Settings[Level].Mines;
225 Settings[Custom].MaxX = MaxX;
226 Settings[Custom].MaxY = MaxY;
227 Settings[Custom].Mines = Mines;
230 if(MaxX != CurrentMaxX || MaxY != CurrentMaxY) {
234 /* if some memory is in use, release it */
236 for(x = 0; x < CurrentMaxX; x++)
241 /* allocate new memory */
242 MineField = (FieldCell **)emalloc(MaxX * sizeof(FieldCell *));
243 for(x = 0; x < MaxX; x++)
244 MineField[x] = (FieldCell *)emalloc(MaxY * sizeof(FieldCell));
249 void GameOver(void) {
254 for(y = 0; y < MaxY; y++)
255 for(x = 0; x < MaxX; x++)
256 switch(MineField[x][y].Picture) {
259 if(MineField[x][y].Mine) {
262 MineField[x][y].Picture = Mark;
263 DisplayCounter(Origin.x + 16, --MinesRemain);
266 MineField[x][y].Picture = Mined;
272 if(! MineField[x][y].Mine) {
273 MineField[x][y].Picture = Fault;
279 void LeftClick(Point Cell) {
281 if(! (Status == Game) || Cell.x < 0 || Cell.y < 0) return;
283 switch(MineField[Cell.x][Cell.y].Picture) {
286 if(MineField[Cell.x][Cell.y].Mine) {
287 MineField[Cell.x][Cell.y].Picture = Explosion;
293 MineField[Cell.x][Cell.y].Picture = MineField[Cell.x][Cell.y].Neighbours;
295 if(! --UnknownCell) {
299 else if(MineField[Cell.x][Cell.y].Neighbours == 0) {
300 if(Cell.x > 0) LeftClick(Pt(Cell.x - 1, Cell.y));
301 if(Cell.y > 0) LeftClick(Pt(Cell.x, Cell.y - 1));
302 if(Cell.x < MaxX - 1) LeftClick(Pt(Cell.x + 1, Cell.y));
303 if(Cell.y < MaxY - 1) LeftClick(Pt(Cell.x, Cell.y + 1));
304 if(Cell.x > 0 && Cell.y > 0) LeftClick(Pt(Cell.x - 1, Cell.y - 1));
305 if(Cell.x > 0 && Cell.y < MaxY - 1) LeftClick(Pt(Cell.x - 1, Cell.y + 1));
306 if(Cell.x < MaxX - 1 && Cell.y > 0) LeftClick(Pt(Cell.x + 1, Cell.y - 1));
307 if(Cell.x < MaxX - 1 && Cell.y < MaxY - 1) LeftClick(Pt(Cell.x + 1, Cell.y + 1));
312 void MiddleClick(Point Cell) {
316 if(! (Status == Game) || Cell.x < 0 || Cell.y < 0) return;
318 switch(MineField[Cell.x][Cell.y].Picture) {
332 if(Cell.x > 0 && MineField[Cell.x - 1][Cell.y].Picture == Mark) Neighbours++;
333 if(Cell.y > 0 && MineField[Cell.x][Cell.y - 1].Picture == Mark) Neighbours++;
334 if(Cell.x < MaxX - 1 && MineField[Cell.x + 1][Cell.y].Picture == Mark) Neighbours++;
335 if(Cell.y < MaxY - 1 && MineField[Cell.x][Cell.y + 1].Picture == Mark) Neighbours++;
336 if(Cell.x > 0 && Cell.y > 0 && MineField[Cell.x - 1][Cell.y - 1].Picture == Mark) Neighbours++;
337 if(Cell.x > 0 && Cell.y < MaxY - 1 && MineField[Cell.x - 1][Cell.y + 1].Picture == Mark) Neighbours++;
338 if(Cell.x < MaxX - 1 && Cell.y > 0 && MineField[Cell.x + 1][Cell.y - 1].Picture == Mark) Neighbours++;
339 if(Cell.x < MaxX - 1 && Cell.y < MaxY - 1 && MineField[Cell.x + 1][Cell.y + 1].Picture == Mark) Neighbours++;
341 if(Neighbours == MineField[Cell.x][Cell.y].Neighbours) {
342 if(Cell.x > 0) LeftClick(Pt(Cell.x - 1, Cell.y));
343 if(Cell.y > 0) LeftClick(Pt(Cell.x, Cell.y - 1));
344 if(Cell.x < MaxX - 1) LeftClick(Pt(Cell.x + 1, Cell.y));
345 if(Cell.y < MaxY - 1) LeftClick(Pt(Cell.x, Cell.y + 1));
346 if(Cell.x > 0 && Cell.y > 0) LeftClick(Pt(Cell.x - 1, Cell.y - 1));
347 if(Cell.x > 0 && Cell.y < MaxY - 1) LeftClick(Pt(Cell.x - 1, Cell.y + 1));
348 if(Cell.x < MaxX - 1 && Cell.y > 0) LeftClick(Pt(Cell.x + 1, Cell.y - 1));
349 if(Cell.x < MaxX - 1 && Cell.y < MaxY - 1) LeftClick(Pt(Cell.x + 1, Cell.y + 1));
353 void RightClick(Point Cell) {
355 if(! (Status == Game) || Cell.x < 0 || Cell.y < 0) return;
358 switch(MineField[Cell.x][Cell.y].Picture) {
360 MineField[Cell.x][Cell.y].Picture = Mark;
362 DisplayCounter(Origin.x + 16, --MinesRemain);
365 MineField[Cell.x][Cell.y].Picture = (UseQuery ? Query : Unknown);
367 DisplayCounter(Origin.x + 16, ++MinesRemain);
370 MineField[Cell.x][Cell.y].Picture = Unknown;
377 fprint(2, "Usage: %s\n", argv0);
381 void main(int argc, char **argv) {
388 if(argc > 0) Usage();
390 if(initdraw(nil, nil, "mines") < 0) {
391 fprint(2, "%s: can't open display: %r\n", argv0);
395 RGB000000 = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x000000ff);
396 RGB0000FF = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x0000ffff);
397 RGB007F00 = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x007f00ff);
398 RGB7F7F7F = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x7f7f7fff);
399 RGBBFBFBF = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xbfbfbfff);
400 RGBFF0000 = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xff0000ff);
401 RGBFFFF00 = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xffff00ff);
402 RGBFFFFFF = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xffffffff);
404 ImageButton[Game] = allocimage(display, Rect(0, 0, 25, 25), RGB24, 0, DNofill);
405 loadimage(ImageButton[Game], ImageButton[Game]->r, SrcButtonGame, ButtonBytes);
407 ImageButton[Push] = allocimage(display, Rect(0, 0, 25, 25), RGB24, 0, DNofill);
408 loadimage(ImageButton[Push], ImageButton[Push]->r, SrcButtonPush, ButtonBytes);
410 ImageButton[Move] = allocimage(display, Rect(0, 0, 25, 25), RGB24, 0, DNofill);
411 loadimage(ImageButton[Move], ImageButton[Move]->r, SrcButtonMove, ButtonBytes);
413 ImageButton[Win] = allocimage(display, Rect(0, 0, 25, 25), RGB24, 0, DNofill);
414 loadimage(ImageButton[Win], ImageButton[Win]->r, SrcButtonWin, ButtonBytes);
416 ImageButton[Oops] = allocimage(display, Rect(0, 0, 25, 25), RGB24, 0, DNofill);
417 loadimage(ImageButton[Oops], ImageButton[Oops]->r, SrcButtonOops, ButtonBytes);
419 ImageSign = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
420 loadimage(ImageSign, ImageSign->r, SrcSign, DigitBytes);
422 ImageDigit[0] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
423 loadimage(ImageDigit[0], ImageDigit[0]->r, SrcDigit0, DigitBytes);
425 ImageDigit[1] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
426 loadimage(ImageDigit[1], ImageDigit[1]->r, SrcDigit1, DigitBytes);
428 ImageDigit[2] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
429 loadimage(ImageDigit[2], ImageDigit[2]->r, SrcDigit2, DigitBytes);
431 ImageDigit[3] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
432 loadimage(ImageDigit[3], ImageDigit[3]->r, SrcDigit3, DigitBytes);
434 ImageDigit[4] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
435 loadimage(ImageDigit[4], ImageDigit[4]->r, SrcDigit4, DigitBytes);
437 ImageDigit[5] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
438 loadimage(ImageDigit[5], ImageDigit[5]->r, SrcDigit5, DigitBytes);
440 ImageDigit[6] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
441 loadimage(ImageDigit[6], ImageDigit[6]->r, SrcDigit6, DigitBytes);
443 ImageDigit[7] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
444 loadimage(ImageDigit[7], ImageDigit[7]->r, SrcDigit7, DigitBytes);
446 ImageDigit[8] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
447 loadimage(ImageDigit[8], ImageDigit[8]->r, SrcDigit8, DigitBytes);
449 ImageDigit[9] = allocimage(display, Rect(0, 0, 11, 21), RGB24, 0, DNofill);
450 loadimage(ImageDigit[9], ImageDigit[9]->r, SrcDigit9, DigitBytes);
452 ImageCell[Empty0] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
453 loadimage(ImageCell[Empty0], ImageCell[Empty0]->r, SrcEmpty0, CellBytes);
455 ImageCell[Empty1] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
456 loadimage(ImageCell[Empty1], ImageCell[Empty1]->r, SrcEmpty1, CellBytes);
458 ImageCell[Empty2] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
459 loadimage(ImageCell[Empty2], ImageCell[Empty2]->r, SrcEmpty2, CellBytes);
461 ImageCell[Empty3] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
462 loadimage(ImageCell[Empty3], ImageCell[Empty3]->r, SrcEmpty3, CellBytes);
464 ImageCell[Empty4] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
465 loadimage(ImageCell[Empty4], ImageCell[Empty4]->r, SrcEmpty4, CellBytes);
467 ImageCell[Empty5] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
468 loadimage(ImageCell[Empty5], ImageCell[Empty5]->r, SrcEmpty5, CellBytes);
470 ImageCell[Empty6] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
471 loadimage(ImageCell[Empty6], ImageCell[Empty6]->r, SrcEmpty6, CellBytes);
473 ImageCell[Empty7] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
474 loadimage(ImageCell[Empty7], ImageCell[Empty7]->r, SrcEmpty7, CellBytes);
476 ImageCell[Empty8] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
477 loadimage(ImageCell[Empty8], ImageCell[Empty8]->r, SrcEmpty8, CellBytes);
479 ImageCell[Unknown] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
480 loadimage(ImageCell[Unknown], ImageCell[Unknown]->r, SrcUnknown, CellBytes);
482 ImageCell[Mark] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
483 loadimage(ImageCell[Mark], ImageCell[Mark]->r, SrcMark, CellBytes);
485 ImageCell[Query] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
486 loadimage(ImageCell[Query], ImageCell[Query]->r, SrcQuery, CellBytes);
488 ImageCell[MouseQuery] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
489 loadimage(ImageCell[MouseQuery], ImageCell[MouseQuery]->r, SrcMouseQuery, CellBytes);
491 ImageCell[Mined] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
492 loadimage(ImageCell[Mined], ImageCell[Mined]->r, SrcMined, CellBytes);
494 ImageCell[Explosion] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
495 loadimage(ImageCell[Explosion], ImageCell[Explosion]->r, SrcExplosion, CellBytes);
497 ImageCell[Fault] = allocimage(display, Rect(0, 0, 15, 15), RGB24, 0, DNofill);
498 loadimage(ImageCell[Fault], ImageCell[Fault]->r, SrcFault, CellBytes);
500 srand(time(0)); /* initialize generator of random numbers */
502 NewMineField(Beginner);
506 einit(Emouse | Ekeyboard);
509 int PushButton = FALSE, Button = FALSE, CurrentButton, ChargedButton = FALSE, MiddleButton = FALSE, LastButton = 0;
512 Point CurrentCell, Cell = Pt(-1, -1);
514 Etimer = etimer(0, 1000);
521 if(Playing && Time < INT_MAX)
522 DisplayCounter(Origin.x -34 + MaxX * 16, ++Time);
527 /* mouse over button? */
528 CurrentButton = FALSE;
529 if(Event.mouse.xy.x > Origin.x + MaxX * 8 && Event.mouse.xy.x < Origin.x + MaxX * 8 + 25 && Event.mouse.xy.y > Origin.y + 17 && Event.mouse.xy.y < Origin.y + 42) CurrentButton = TRUE;
531 /* mouse over any cell? */
532 CurrentCell = Pt(-1, -1);
533 if(Event.mouse.xy.x > Origin.x + 12 && Event.mouse.xy.x < Origin.x + 12 + MaxX * 16)
534 CurrentCell.x = (Event.mouse.xy.x - Origin.x - 13) / 16;
535 if(Event.mouse.xy.y > Origin.y + 57 && Event.mouse.xy.y < Origin.y + 57 + MaxY * 16)
536 CurrentCell.y = (Event.mouse.xy.y - Origin.y - 58) / 16;
538 /* pressed mouse button */
539 if(Event.mouse.buttons > LastButton) {
542 switch(Event.mouse.buttons) {
547 if(PushButton) DrawButton(Status);
551 if(! (CurrentCell.x < 0) && ! (CurrentCell.y < 0)) {
552 switch(Event.mouse.buttons) {
554 ChargedButton = TRUE;
555 MiddleButton = FALSE;
558 if(LastButton == 0) ChargedButton = TRUE;
562 if(LastButton == 0) RightClick(CurrentCell);
563 else MiddleButton = TRUE;
566 ChargedButton = TRUE;
569 if(ChargedButton && Status == Game) DrawButton(Move);
573 if(PushButton && CurrentButton != Button) {
574 if(CurrentButton) DrawButton(Push);
575 else DrawButton(Status);
576 Button = CurrentButton;
579 if(ChargedButton && (! eqpt(CurrentCell, Cell) || Event.mouse.buttons != LastButton) && Status == Game) {
580 if(! (Cell.x < 0) && ! (Cell.y < 0)) {
582 if(Cell.x > 0) RecoverCell(Pt(Cell.x - 1, Cell.y));
583 if(Cell.y > 0) RecoverCell(Pt(Cell.x, Cell.y - 1));
584 if(Cell.x < MaxX - 1) RecoverCell(Pt(Cell.x + 1, Cell.y));
585 if(Cell.y < MaxY - 1) RecoverCell(Pt(Cell.x, Cell.y + 1));
586 if(Cell.x > 0 && Cell.y > 0) RecoverCell(Pt(Cell.x - 1, Cell.y - 1));
587 if(Cell.x > 0 && Cell.y < MaxY - 1) RecoverCell(Pt(Cell.x - 1, Cell.y + 1));
588 if(Cell.x < MaxX - 1 && Cell.y > 0) RecoverCell(Pt(Cell.x + 1, Cell.y - 1));
589 if(Cell.x < MaxX - 1 && Cell.y < MaxY - 1) RecoverCell(Pt(Cell.x + 1, Cell.y + 1));
592 if(! (Cell.x < 0) && ! (Cell.y < 0) && ! (Event.mouse.buttons < LastButton)) {
595 if(Cell.x > 0) MouseCell(Pt(Cell.x - 1, Cell.y));
596 if(Cell.y > 0) MouseCell(Pt(Cell.x, Cell.y - 1));
597 if(Cell.x < MaxX - 1) MouseCell(Pt(Cell.x + 1, Cell.y));
598 if(Cell.y < MaxY - 1) MouseCell(Pt(Cell.x, Cell.y + 1));
599 if(Cell.x > 0 && Cell.y > 0) MouseCell(Pt(Cell.x - 1, Cell.y - 1));
600 if(Cell.x > 0 && Cell.y < MaxY - 1) MouseCell(Pt(Cell.x - 1, Cell.y + 1));
601 if(Cell.x < MaxX - 1 && Cell.y > 0) MouseCell(Pt(Cell.x + 1, Cell.y - 1));
602 if(Cell.x < MaxX - 1 && Cell.y < MaxY - 1) MouseCell(Pt(Cell.x + 1, Cell.y + 1));
607 /* released mouse button */
608 if(Event.mouse.buttons < LastButton) {
609 if(PushButton && CurrentButton) {
617 if(MiddleButton) MiddleClick(Cell);
618 else LeftClick(Cell);
622 ChargedButton = FALSE;
625 LastButton = Event.mouse.buttons;
628 if(Key == Ekeyboard) {
638 NewMineField(Beginner);
643 NewMineField(Advanced);
648 NewMineField(Expert);