]> Shamusworld >> Repos - warehouse-man-deluxe/blob - src/gamewidget.cpp
4a3092205f74f0c4170a8b3036d1e93d10d88dd9
[warehouse-man-deluxe] / src / gamewidget.cpp
1 //
2 // gamewidget.cpp: Main game window widget
3 //
4 // by James Hammons
5 // (C) 2013 Underground Software
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 //
9 // Who  When        What
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  03/01/2014  Created this file
12 //
13
14 #include "gamewidget.h"
15 #include <unistd.h>                     // for usleep()
16 #include "gameboard.h"
17
18
19 GameWidget::GameWidget(QWidget * parent/*= 0*/): QWidget(parent),
20         level(1), gameBoard(new GameBoard(level)),
21         animating(false), boxMoving(false)
22 //      score(new QLabel)
23 {
24 //      score->setTextFormat(Qt::PlainText);
25         setFixedSize(580, 520);
26 //      gameBoard = new GameBoard(1);
27 }
28
29
30 GameWidget::~GameWidget(void)
31 {
32 }
33
34
35 void GameWidget::paintEvent(QPaintEvent * /*event*/)
36 {
37         // TO DO:
38         // Optimizations: Create a member variable that has a bitmap in it,
39         // tile it with the felt in OnCreate(), blit as background instead of
40         // FillRect(r, brWhite). Also need to keep track of client rect.
41         // Possibly have 2 bitmaps as member vars, so keep bm construction to a minimum...
42
43         QPainter painter(this);
44 //      QRect rcUpdate = dc.m_ps.rcPaint; // Update rect...
45 //      QRect rcUpdate = QRect(0, 0, 580, 520);                 // Update rect?
46
47         maxLength = 60;
48         int ptr = 0;
49
50         for(int y=0; y<gameBoard->height; y++)
51         {
52                 for(int x=0; x<gameBoard->width; x++)
53                 {
54                         int tile = gameBoard->board[ptr++];
55                         painter.setPen(QPen(Qt::black, 2.0, Qt::SolidLine));
56                         painter.setBrush(QBrush(Qt::black));
57
58                         if (tile == GTWall)
59                         {
60                                 painter.setBrush(QBrush(Qt::white));
61                                 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
62                         }
63                         else if (tile == GTBox)
64                         {
65                                 if (!(boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y)))
66                                 {
67                                         painter.setBrush(QBrush(Qt::red));
68                                         painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
69                                 }
70                         }
71                         else if (tile == GTBoxSpot)
72                         {
73                                 painter.setBrush(QBrush(Qt::magenta));
74                                 painter.drawRect((x * maxLength) + 20, (y * maxLength) + 20, maxLength - 40, maxLength - 40);
75                         }
76                         else if (tile == (GTBox | GTBoxSpot))
77                         {
78                                 if (!(boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y)))
79                                 {
80                                         painter.setBrush(QBrush(Qt::green));
81                                         painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
82                                 }
83                                 else
84                                 {
85                                         painter.setBrush(QBrush(Qt::magenta));
86                                         painter.drawRect((x * maxLength) + 20, (y * maxLength) + 20, maxLength - 40, maxLength - 40);
87                                 }
88                         }
89
90                         if ((gameBoard->playerX == x) && (gameBoard->playerY == y) && !animating)
91                         {
92                                 painter.setBrush(QBrush(Qt::yellow));
93                                 painter.drawEllipse((x * maxLength) + 10, (y * maxLength) + 10, maxLength - 20, maxLength - 20);
94                         }
95                 }
96
97                 if (animating)
98                 {
99                         painter.setBrush(QBrush(Qt::yellow));
100                         painter.drawEllipse(playerX + 10, playerY + 10, maxLength - 20, maxLength - 20);
101                 }
102
103                 if (boxMoving)
104                 {
105                         painter.setBrush(QBrush(Qt::red));
106                         painter.drawRect(boxX, boxY, maxLength, maxLength);
107                 }
108         }
109
110
111 #if 0
112         DrawBoard(&painter, rcUpdate);
113
114         // Draw the "loose" cards....
115
116         if (hitStack)
117         {
118                 for(int i=stackStart.y(); i<19; i++)
119                 {
120                         int card = solBoard[stackStart.x()][i];
121
122                         if (card != -1)
123                         {
124                                 if (solBoard[stackStart.x()][i + 1] == -1) // Draw full card
125                                         cdtDraw(&painter, stackPos.x(), stackPos.y() + ((i - stackStart.y()) * 18),
126                                                 myDeck.GetCardAtPos(card), FACEUP);
127                                 else                                   // Draw partial card
128                                         cdtDraw(&painter, stackPos.x(), stackPos.y() + ((i - stackStart.y()) * 18),
129                                                 myDeck.GetCardAtPos(card), FACEUP, 20);
130                         }
131                 }
132         }
133
134         if (hitDiscard)
135                 cdtDraw(&painter, stackPos.x(), stackPos.y(), myDeck.GetCardAtPos(stack2[stack2p]),
136                         FACEUP);
137
138         if (nHitAce != 0)
139                 cdtDraw(&painter, stackPos.x(), stackPos.y(), nAce[nHitAce - 1], FACEUP);
140
141         if (m_bFreeCard)  // For card animations...
142         {
143                 for(SCardInfo * pCard=m_pFirstCard; pCard; pCard=pCard->pNext)
144                         cdtDraw(&painter, pCard->nXPos, pCard->nYPos, pCard->nCard, FACEUP);
145         }
146 #endif
147 }
148
149
150 void GameWidget::mousePressEvent(QMouseEvent * event)
151 {
152         if (event->button() == Qt::LeftButton)
153         {
154 //              OnLButtonDown(event->pos());
155                 event->accept();
156         }
157 }
158
159
160 void GameWidget::mouseMoveEvent(QMouseEvent * event)
161 {
162         if (event->buttons() & Qt::LeftButton)
163         {
164 //              OnMouseMove(event->pos());
165                 event->accept();
166         }
167 }
168
169
170 void GameWidget::mouseReleaseEvent(QMouseEvent * event)
171 {
172         if (event->button() == Qt::LeftButton)
173         {
174 //              OnLButtonUp(event->pos());
175                 event->accept();
176         }
177 }
178
179
180 void GameWidget::mouseDoubleClickEvent(QMouseEvent * event)
181 {
182         if (event->button() == Qt::LeftButton)
183         {
184 //              OnLButtonDblClk(event->pos());
185                 event->accept();
186         }
187 }
188
189
190 void GameWidget::keyPressEvent(QKeyEvent * event)
191 {
192         int key = event->key();
193         float deltaX = 0, deltaY = 0;
194         float px = (float)(gameBoard->playerX * maxLength);
195         float py = (float)(gameBoard->playerY * maxLength);
196         float bx = px, by = py;
197
198         if (key == Qt::Key_Up)
199         {
200                 boxMoving = gameBoard->IsBoxNOfPlayer();
201                 int moveType = gameBoard->MovePlayerN();
202
203                 if (moveType == PMInvalid)
204                         return;
205
206                 deltaY = -1.0;
207         }
208         else if (key == Qt::Key_Down)
209         {
210                 boxMoving = gameBoard->IsBoxSOfPlayer();
211
212                 if (gameBoard->MovePlayerS() == PMInvalid)
213                         return;
214
215                 deltaY = +1.0;
216         }
217         else if (key == Qt::Key_Left)
218         {
219                 boxMoving = gameBoard->IsBoxWOfPlayer();
220
221                 if (gameBoard->MovePlayerW() == PMInvalid)
222                         return;
223
224                 deltaX = -1.0;
225         }
226         else if (key == Qt::Key_Right)
227         {
228                 boxMoving = gameBoard->IsBoxEOfPlayer();
229
230                 if (gameBoard->MovePlayerE() == PMInvalid)
231                         return;
232
233                 deltaX = +1.0;
234         }
235         else
236                 return;
237
238         animating = true;
239         update();
240
241         if (boxMoving)
242         {
243                 movingBoxPositionX = gameBoard->playerX + (int)deltaX;
244                 movingBoxPositionY = gameBoard->playerY + (int)deltaY;
245                 bx += deltaX * (float)maxLength;
246                 by += deltaY * (float)maxLength;
247         }
248
249         int steps = 15;
250         float stepSize = (float)maxLength / (float)steps;
251         deltaX *= stepSize, deltaY *= stepSize;
252
253         for(int i=0; i<steps; i++)
254         {
255                 px += deltaX;
256                 py += deltaY;
257                 playerX = (int)px;
258                 playerY = (int)py;
259                 bx += deltaX;
260                 by += deltaY;
261                 boxX = (int)bx;
262                 boxY = (int)by;
263                 repaint();
264                 Pause(3);
265         }
266
267         animating = boxMoving = false;
268
269         // Only update if a key we recognize has been pressed!
270         update();
271
272         if (gameBoard->GameHasBeenWon())
273                 emit GameWasWon();
274 }
275
276
277 void GameWidget::keyReleaseEvent(QKeyEvent * event)
278 {
279 }
280
281
282 void GameWidget::NextLevel(void)
283 {
284         level++;
285         delete gameBoard;
286         gameBoard = new GameBoard(level);
287         update();
288 }
289
290
291 void GameWidget::ResetLevel(void)
292 {
293         gameBoard->ResetGame();
294         update();
295 }
296
297
298 #if 0
299 bool GameWidget::CreateBackground(void)
300 {
301         char BGRes[27][64] = {
302                 ":/res/grfttile.bmp",
303                 ":/res/cloth_6.bmp",
304                 ":/res/bg_tech_3.bmp",
305                 ":/res/bg_tech_2.bmp",
306                 ":/res/bg_tech_1.bmp",
307                 ":/res/bg_weave_3.bmp",
308                 ":/res/bg_weave_2.bmp",
309                 ":/res/bg_clouds_2.bmp",
310                 ":/res/bg_floor_plate.bmp",
311                 ":/res/bg_marble_b.bmp",
312                 ":/res/bg_marble_g.bmp",
313                 ":/res/bg_marble_p.bmp",
314                 ":/res/bg_marble_r.bmp",
315                 ":/res/bg_marble_rb.bmp",
316                 ":/res/bg_money_1.bmp",
317                 ":/res/bg_pinstripe2.bmp",
318                 ":/res/bg_pinstripe7.bmp",
319                 ":/res/bg_raindrops_large.bmp",
320                 ":/res/bg_raindrops_small.bmp",
321                 ":/res/bg_stucco.bmp",
322                 ":/res/bg_wood_w.bmp",
323                 ":/res/bg_wood_b1.bmp",
324                 ":/res/bg_wood_d.bmp",
325                 ":/res/bg_wood_f.bmp",
326                 ":/res/bg_wood_mh.bmp",
327                 ":/res/bg_wood_mv.bmp",
328                 ":/res/bg_wood_ro.bmp"
329         };
330
331         QPalette pal = palette();
332         pal.setBrush(backgroundRole(), QBrush(QPixmap(BGRes[m_nBackground])));
333         setAutoFillBackground(true);
334         setPalette(pal);
335
336         return true; // Ignore errors for now...
337 }
338
339
340 void GameWidget::DrawBoard(QPainter * painter, QRect r)
341 {
342         // Use "r" as clipping rect--only draw what's necessary
343
344 //      pDC->BitBlt(r.left, r.top, r.Width(), r.Height(), pDC2, r.left, r.top, SRCCOPY);
345
346         // Draw the solitaire board...
347
348         for(int i=0; i<7; i++)
349         {
350                 int y = 126; //130-4;
351
352                 for(int j=0; j<19; j++)
353                 {
354                         int card = solBoard[i][j];
355
356                         if (card != -1 && !(hitStack && (i == stackStart.x()) && (j >= stackStart.y())))
357                         {
358                                 int nLinesToDraw = 0; // Default--draws whole card
359
360                                 if (solBoard[i][j + 1] != -1 && !(hitStack && (i == stackStart.x()) && (j + 1 >= stackStart.y())))
361                                 {
362                                         nLinesToDraw = 6;
363
364                                         if (myDeck.IsFaceUp(card))
365                                                 nLinesToDraw += 14;
366                                 }
367
368                                 int x = 10 + (i * (CARD_WIDTH + 8));//, y = 130 + (j * 4);
369                                 y += 4;
370
371                                 if (j > 0)
372                                 {
373                                         if (myDeck.IsFaceUp(solBoard[i][j - 1]))  // Previous card...
374                                                 y += 14;
375                                 }
376
377                                 //wil wok??? mebbe... YESH!!!!!!!!!!!!!
378                                 QRect cardRect(x, y, CARD_WIDTH, (nLinesToDraw ? nLinesToDraw : CARD_HEIGHT));
379
380                                 if (r.intersects(cardRect))
381                                         cdtDraw(painter, x, y, (myDeck.IsFaceUp(card) ? myDeck.GetCardAtPos(card)
382                                                 : nCardBack), FACEUP, nLinesToDraw);
383                         }
384                 }
385         }
386
387         for(int i=0; i<4; i++)
388         {
389                 if (nHitAce == i + 1)
390                 {
391                         if (((nAce[i] - 1) % 13) != 0)
392                                 cdtDraw(painter, 200 + ((CARD_WIDTH + 4) * i), 7, nAce[i] - 1, FACEUP);
393                         else
394                                 cdtDraw(painter, 200 + ((CARD_WIDTH + 4) * i), 7, 0, INVISIBLEGHOST);
395                 }
396                 else
397                 {
398                         if (nAce[i] != -1)
399                                 cdtDraw(painter, 200 + ((CARD_WIDTH + 4) * i), 7, nAce[i], FACEUP);
400                         else
401                                 cdtDraw(painter, 200 + ((CARD_WIDTH + 4) * i), 7, 0, INVISIBLEGHOST);
402                 }
403         }
404         
405         if (stack1p != -1)
406                 cdtDraw(painter, 5, 7, nCardBack, FACEUP);
407         else
408         {
409 #if 0
410                 if (m_bShowX)
411                         cdtDraw(painter, 5, 7, 0, DECKX);
412                 else
413                         cdtDraw(painter, 5, 7, 0, DECKO);
414 #else
415                 cdtDraw(painter, 5, 7, 0, (m_bShowX ? DECKX : DECKO));
416 #endif
417         }
418
419         if (stack2p != -1)
420         {
421                 if (!hitDiscard)
422                 {
423                         for(int k=0; k<m_nNumToSplay; k++)
424                                 cdtDraw(painter, 5 + CARD_WIDTH + 6 + (k * 12), 7 + (k * 2),
425                                         myDeck.GetCardAtPos(stack2[stack2p - (m_nNumToSplay - k - 1)]), FACEUP);
426                 }
427                 else
428                 {
429                         if (stack2p != 0)
430                         {
431                                 if (m_nNumToSplay == 1)
432                                         cdtDraw(painter, 5 + CARD_WIDTH + 6, 7, myDeck.GetCardAtPos(stack2[stack2p - 1]), FACEUP);
433                                 else
434                                         for(int k=0; k<m_nNumToSplay-1; k++)
435                                                 cdtDraw(painter, 5 + CARD_WIDTH + 6 + (k * 12), 7 + (k * 2),
436                                                         myDeck.GetCardAtPos(stack2[stack2p - (m_nNumToSplay - k - 1)]), FACEUP);
437                         }
438                 }
439         }
440 }
441
442
443 void GameWidget::OnLButtonDown(QPoint point) 
444 {
445         dcHitStack = dcHitDiscard = false;  // For double clicking...
446         m_bTouchedGame = true;              // Game has been attempted!
447
448         if (!allowUserInput)
449                 return;
450
451         mouseDown = true;
452
453         // Set undo up...
454         for(int i=0; i<7; i++)
455                 for(int j=0; j<20; j++)
456                         solBoardUndo[i][j] = solBoard[i][j];
457
458         for(int i=0; i<24; i++)
459                 stack1Undo[i] = stack1[i], stack2Undo[i] = stack2[i];
460
461         for(int i=0; i<4; i++)
462                 nAceUndo[i] = nAce[i];
463
464         stack1pUndo = stack1p, stack2pUndo = stack2p;
465         m_nScoreUndo = m_nScore;
466         m_nExhaustedDeckUndo = m_nExhaustedDeck;
467         m_nNumToSplayUndo = m_nNumToSplay;
468         m_bShowXUndo = m_bShowX;
469         m_bCanUndo = false;
470
471         // Check for a hit on the tableaux...
472
473         for(int i=0; i<7; i++)
474         {
475                 QRect r;
476                 r.setLeft(10 + (i * (CARD_WIDTH + 8)));
477                 r.setRight(r.left() + CARD_WIDTH - 1);
478                 r.setTop(130);
479                 int nCards = 0;
480
481                 for(int j=0; j<19; j++)
482                 {
483                         if (solBoard[i][j] != -1)
484                         {
485                                 if (myDeck.IsFaceUp(solBoard[i][j]))
486                                 {
487                                         if ((j == 18) || (solBoard[i][j + 1] == -1))
488                                                 r.setBottom(r.top() + CARD_HEIGHT - 1);
489                                         else
490                                                 r.setBottom(r.top() + 17);
491
492                                         if (r.contains(point))
493                                         {
494                                                 hitStack = dcHitStack = true;
495                                                 stackStart = QPoint(i, j);
496                                                 mouseOffset = QPoint(point.x() - r.left(), point.y() - r.top());
497                                                 stackPos = QPoint(point.x() - mouseOffset.x(), point.y() - mouseOffset.y());
498                                                 QRect rcUpdate(r.left(), r.top(), r.width(), CARD_HEIGHT - 1); //wil wok?
499                                                 return;
500                                         }
501
502                                         r.setTop(r.top() + 18);
503                                 }
504                                 else
505                                 {
506                                         if (j != 18)
507                                         {
508                                                 if (solBoard[i][j + 1] == -1)
509                                                 {
510                                                         r.setBottom(r.top() + CARD_HEIGHT - 1);
511
512                                                         if (r.contains(point))
513                                                         {
514                                                                 myDeck.ToggleCardFacing(solBoard[i][j]);  // Turn over that last card
515
516 #if HAVE_SOUND
517                                                                 if (bSoundOn)
518                                                                         PlaySound(IDW_CARDFLIP);
519 #endif
520
521                                                                 update(r); //wil wok?
522
523                                                                 // Scoring...
524                                                                 if (!m_bVegasStyle)
525                                                                 {
526                                                                         m_nScore += 5;
527                                                                         emit UpdateScore(m_nScore);
528                                                                 }
529
530                                                                 return;
531                                                         }
532                                                 }
533                                         }
534
535                                         r.setTop(r.top() + 4);
536                                 }
537
538                                 nCards++;
539                         }
540                 }
541         }
542
543         // Check for hit on discard stack
544
545         int nCX = 5 + CARD_WIDTH + 6 + ((m_nNumToSplay - 1) * 12);
546         int nCY = 7 + ((m_nNumToSplay - 1) * 2);
547
548         if (QRect(nCX, nCY, CARD_WIDTH - 1, CARD_HEIGHT - 1).contains(point))
549         {
550                 if (stack2p != -1)
551                 {
552                         hitDiscard = dcHitDiscard = true;
553                         mouseOffset = QPoint(point.x() - (5 + CARD_WIDTH + 6 + ((m_nNumToSplay - 1) * 12)),
554                                 point.y() - (7 + ((m_nNumToSplay - 1) * 2)));
555                         stackPos = QPoint(point.x() - mouseOffset.x(), point.y() - mouseOffset.y());
556                         return;
557                 }
558         }
559
560         // Check for hit on remaining deck
561
562         if (QRect(5, 7, 5 + CARD_WIDTH - 1, 7 + CARD_HEIGHT - 1).contains(point))
563         {
564                 m_bCanUndo = true;
565
566                 if (stack1p == -1)  // I.e. it's empty...
567                 {
568                         // Scoring...
569                         if ((m_bDrawThree && (m_nExhaustedDeck == 3))
570                                 || (!m_bDrawThree && (m_nExhaustedDeck == 1)))
571                         {
572                                 if (!m_bVegasStyle)
573                                 {
574                                         m_nExhaustedDeck = 0;
575                                         m_nScore -= (m_bDrawThree ? 20 : 100);
576
577                                         if (m_nScore < 0)
578                                                 m_nScore = 0;
579
580                                         emit UpdateScore(m_nScore);
581                                 }
582                         }
583                         if (!m_bVegasStyle || (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck < 3))
584                                         || (!m_bDrawThree && (m_nExhaustedDeck < 1)))))
585                         {
586                                 for(; stack2p != -1; stack2p--)
587                                 {
588                                         stack1p++;
589                                         stack1[stack1p] = stack2[stack2p];
590                                 }
591
592 #if HAVE_SOUND
593                                 if (bSoundOn)
594                                         PlaySound(IDW_CARDKNOCK);
595 #endif
596                         }
597                 }
598                 else
599                 {
600                         m_nNumToSplay = 0;
601
602                         for(int i=0; i<(m_bDrawThree ? 3 : 1); i++)
603                         {
604                                 if (stack1p != -1)  // I.e., there are cards left...
605                                 {
606                                         stack2[++stack2p] = stack1[stack1p--];
607
608 #if HAVE_SOUND
609                                         if (bSoundOn)
610                                         {
611                                                 PlaySound(IDW_CARDFLIP);
612                                                 // Pause
613                                                 Pause(55);
614                                         }
615 #endif
616
617                                         m_nNumToSplay++;
618                                 }
619                         }
620
621                         if (stack1p == -1)  // This is done here because it's right!
622                         {
623                                 m_nExhaustedDeck++;
624
625                                 if (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck == 3))
626                                         || (!m_bDrawThree && (m_nExhaustedDeck == 1))))
627                                         m_bShowX = true;
628                         }
629                 }
630
631                 mouseOffset = QPoint(point.x() - 5, point.y() - 7);
632
633                 QRect inv1(5, 7, CARD_WIDTH, CARD_HEIGHT),
634                         inv2(5 + CARD_WIDTH + 6, 7, (2 * 12) + CARD_WIDTH, (2 * 2) + CARD_HEIGHT);
635                 update(inv1);
636                 update(inv2);
637         }
638
639         // Check for hit on ace piles
640
641         for(int i=0; i<4; i++)
642         {
643                 QRect aceRect(200 + ((CARD_WIDTH + 4) * i), 7, CARD_WIDTH - 1, CARD_HEIGHT - 1);
644
645                 if (aceRect.contains(point) && (nAce[i] > -1))
646                 {
647                         nHitAce = i + 1;
648 //                      mouseOffset = QPoint(point.x() - (200 + ((CARD_WIDTH + 4) * i)), point.y() - 7);
649                         mouseOffset = QPoint(point.x() - aceRect.x(), point.y() - aceRect.y());
650                         stackPos = QPoint(point.x() - mouseOffset.x(), point.y() - mouseOffset.y());
651                         return;
652                 }
653         }
654 }
655
656
657 void GameWidget::OnLButtonUp(QPoint point) 
658 {
659         if (!allowUserInput)
660                 return;
661
662         point -= mouseOffset; // ?? bad form!
663
664         if (hitStack || hitDiscard || (nHitAce != 0))
665         {
666                 QRect tabl[7];
667
668                 for(int i=0; i<7; i++)  // Compute valid rects at bottoms of stacks...
669                 {
670                         tabl[i].setLeft(10 + (i * (CARD_WIDTH + 8)));
671                         tabl[i].setRight(tabl[i].left() + CARD_WIDTH - 1);
672                         tabl[i].setTop(130);
673
674                         for(int j=0; j<19; j++)
675                         {
676                                 if ((solBoard[i][j] == -1)
677                                         || (hitStack && (i == stackStart.x()) && (j == stackStart.y())))
678                                 {
679                                         if (j > 0)
680                                         {
681                                                 for(int k=0; k<j-1; k++)
682                                                 {
683                                                         if (!myDeck.IsFaceUp(solBoard[i][k]))
684                                                                 tabl[i].setTop(tabl[i].top() + 4);
685                                                         else
686                                                                 tabl[i].setTop(tabl[i].top() + 17);
687                                                 }
688                                         }
689
690                                         tabl[i].setBottom(tabl[i].top() + CARD_HEIGHT - 1);
691                                         break;
692                                 }
693                         }
694                 }
695
696 //              stackPos = QPoint(point.x() - mouseOffset.x(), point.y() - mouseOffset.y());
697 //              QRect c(point.x(), point.y(), CARD_WIDTH - 1, CARD_HEIGHT - 1);
698 //              QRect c(point.x() - mouseOffset.x(), point.y() - mouseOffset.y(), CARD_WIDTH - 1, CARD_HEIGHT - 1);
699                 QRect c(stackPos.x(), stackPos.y(), CARD_WIDTH - 1, CARD_HEIGHT - 1);
700                 QRect a[4];
701                 a[0] = QRect(200, 7, CARD_WIDTH - 1, CARD_HEIGHT - 1);
702                 a[1] = QRect(200 + ((CARD_WIDTH + 4) * 1), 7, CARD_WIDTH - 1, CARD_HEIGHT - 1);
703                 a[2] = QRect(200 + ((CARD_WIDTH + 4) * 2), 7, CARD_WIDTH - 1, CARD_HEIGHT - 1);
704                 a[3] = QRect(200 + ((CARD_WIDTH + 4) * 3), 7, CARD_WIDTH - 1, CARD_HEIGHT - 1);
705
706                 bool bHitAce[4];
707                 bHitAce[0] = c.intersects(a[0]);
708                 bHitAce[1] = c.intersects(a[1]);
709                 bHitAce[2] = c.intersects(a[2]);
710                 bHitAce[3] = c.intersects(a[3]);
711
712                 // Check to see if hit more than one ace & pick the one that's closer
713                 for(int i=0; i<3; i++)
714                 {
715                         if (bHitAce[i] && bHitAce[i + 1] && (nAce[i] == -1) && (nAce[i + 1] == -1))
716                         {
717                                 if (c.intersected(a[i]).width() > c.intersected(a[i + 1]).width())
718                                         bHitAce[i + 1] = false;
719                                 else
720                                         bHitAce[i] = false;
721
722                                 break;
723                         }
724                 }
725
726                 bool bMovedToAce = false;
727
728                 for(int i=0; i<4; i++)
729                 {
730                         if (bHitAce[i] && IsValidMoveToAce(nAce[i]))
731                         {
732                                 m_bCanUndo = true;
733
734                                 if (hitStack)
735                                         nAce[i] = myDeck.GetCardAtPos(solBoard[stackStart.x()][stackStart.y()]),
736                                         solBoard[stackStart.x()][stackStart.y()] = -1;
737
738                                 if (hitDiscard)
739                                 {
740                                         nAce[i] = myDeck.GetCardAtPos(stack2[stack2p--]);
741
742                                         if (m_nNumToSplay != 1)
743                                                 m_nNumToSplay--;
744                                 }
745
746                                 if (nHitAce != 0)
747                                 {
748                                         nAce[i] = nAce[nHitAce - 1];
749                                         int nCard = nAce[nHitAce - 1];
750                                         nAce[nHitAce - 1] = ((nCard - 1) % 13 == 0 ? -1 : nCard - 1);
751                                         break;
752                                 }
753
754 #if HAVE_SOUND
755                                 if (bSoundOn)
756                                         PlaySound(IDW_CARDPLACE);
757 #endif
758
759                                 bMovedToAce = true;
760
761                                 // Scoring...
762 #if 0
763                                 if (m_bVegasStyle)
764                                         m_nScore += 5;
765                                 else
766                                         m_nScore += 10;
767 #else
768                                 m_nScore += (m_bVegasStyle ? 5 : 10);
769 #endif
770
771                                 emit UpdateScore(m_nScore);
772                                 break;
773                         }
774                 }
775
776                 if (!bMovedToAce) // No aces, so check for stacks
777                 {
778                         for(int i=0; i<7; i++)
779                         {
780                                 if (c.intersects(tabl[i]) && IsValidMoveToTableaux(i))
781                                 {
782                                         m_bCanUndo = true;
783
784 #if HAVE_SOUND
785                                         if (bSoundOn)
786                                                 PlaySound(IDW_CARDPLACE);
787 #endif
788
789                                         if (hitStack && (i != stackStart.x()))
790                                         {
791                                                 int cnt = stackStart.y();
792
793                                                 for(int k=0; k<19; k++)
794                                                 {
795                                                         if (solBoard[i][k] == -1)
796                                                         {
797                                                                 solBoard[i][k] = solBoard[stackStart.x()][cnt];
798                                                                 solBoard[stackStart.x()][cnt] = -1;
799                                                                 cnt++;
800                                                         }
801
802                                                         if (solBoard[stackStart.x()][cnt] == -1) // Done copying?
803                                                                 break;
804                                                 }
805
806                                                 break;
807                                         }
808
809                                         if (hitDiscard)
810                                         {
811                                                 for(int k=0; k<19; k++)
812                                                 {
813                                                         if (solBoard[i][k] == -1)
814                                                         {
815                                                                 solBoard[i][k] = stack2[stack2p--];
816                                                                 myDeck.SetCardFaceUp(solBoard[i][k]);
817
818                                                                 // Scoring...
819                                                                 if (!m_bVegasStyle)
820                                                                 {
821                                                                         m_nScore += 5;
822                                                                         emit UpdateScore(m_nScore);
823                                                                 }
824
825                                                                 if (m_nNumToSplay != 1)
826                                                                         m_nNumToSplay--;
827
828                                                                 break;
829                                                         }
830                                                 }
831
832                                                 break;
833                                         }
834
835                                         if (nHitAce != 0)
836                                         {
837                                                 // handle moving to tableaux here...
838                                                 for(int k=0; k<19; k++)
839                                                 {
840                                                         if (solBoard[i][k] == -1)
841                                                         {
842                                                                 int nCard = nAce[nHitAce - 1];
843
844                                                                 for(int t=0; t<52; t++)  // We have to find da damn thing...
845                                                                 {
846                                                                         if (myDeck.GetCardAtPos(t) == nCard)
847                                                                         {
848                                                                                 solBoard[i][k] = t;
849                                                                                 break;
850                                                                         }
851                                                                 }
852
853                                                                 nAce[nHitAce - 1] = ((nCard - 1) % 13 == 0 ? -1 : nCard - 1);
854                                                                 myDeck.SetCardFaceUp(solBoard[i][k]);
855
856                                                                 // Scoring...
857 #if 0
858                                                                 if (!m_bVegasStyle)
859                                                                         m_nScore -= 15;
860                                                                 else
861                                                                         m_nScore -= 5;
862 #else
863                                                                 m_nScore -= (m_bVegasStyle ? 5 : 15);
864 #endif
865
866                                                                 emit UpdateScore(m_nScore);
867                                                                 break;
868                                                         }
869                                                 }
870
871                                                 break;
872                                         }
873                                 }
874                         }
875                 }
876
877                 update();
878         }
879
880         mouseDown = hitStack = hitDiscard = false;
881         nHitAce = 0;
882
883         if (bAutoRemove)
884                 HandleAutoRemove();
885
886         if (PlayerWon())
887         {
888                 emit UpdateScore(m_nScore);
889                 HandleStatistics();
890                 m_bWonLastGame = true;
891                 m_bCanUndo = false;
892
893 #if HAVE_SOUND
894                 if (bSoundOn)
895                 {
896                         QString id[] = { IDW_WINNER1, IDW_WINNER2, IDW_WINNER3, IDW_WINNER4, IDW_WINNER5 };
897                         srand((unsigned)time(NULL));
898                         int nWaveNum = rand() % 5;
899                         PlaySound(id[nWaveNum]);
900                 }
901 #endif
902
903                 QMessageBox::information(this, "MAC Solitaire", "Congratulations!\nYou won!");
904                 allowUserInput = false;
905         }
906 }
907
908
909 void GameWidget::OnMouseMove(QPoint point) 
910 {
911         if (mouseDown && (hitStack || hitDiscard || (nHitAce != 0)))
912         {
913                 int nHeight = 0;
914
915                 if (hitStack)
916                 {
917                         for(int i=stackStart.y(); i<19; i++)
918                                 if (solBoard[stackStart.x()][i] != -1)
919                                         nHeight += 18;
920                 }
921                 else
922                         nHeight = 18;
923
924                 nHeight += CARD_HEIGHT - 18;
925
926                 QRect rcOld(stackPos.x(), stackPos.y(), CARD_WIDTH,
927                         nHeight); // Find old position for repainting...
928
929                 stackPos = QPoint(point.x() - mouseOffset.x(), point.y() - mouseOffset.y());
930
931                 QRect rcNew(stackPos.x(), stackPos.y(), CARD_WIDTH,
932                         nHeight); // Find new position
933                 QRect rcUpdate = rcOld.united(rcNew);
934                 update(rcUpdate); //wil wok? YESH!
935         }
936 }
937
938
939 void GameWidget::OnLButtonDblClk(QPoint point) 
940 {
941         if (dcHitStack || dcHitDiscard)
942         {
943                 hitStack = dcHitStack, hitDiscard = dcHitDiscard;
944
945                 for(int i=0; i<4; i++)
946                 {
947                         if (IsValidMoveToAce(nAce[i]))
948                         {
949                                 if (hitStack)
950                                 {
951                                         nAce[i] = myDeck.GetCardAtPos(solBoard[stackStart.x()][stackStart.y()]);
952                                         solBoard[stackStart.x()][stackStart.y()] = -1;
953                                 }
954                                 else
955                                 {
956                                         nAce[i] = myDeck.GetCardAtPos(stack2[stack2p--]);
957
958                                         if (m_nNumToSplay != 1)
959                                                 m_nNumToSplay--;
960                                 }
961
962                                 update();
963
964 #if HAVE_SOUND
965                                 if (bSoundOn)
966                                         PlaySound(IDW_ZIP);
967 #endif
968
969                                 // Scoring...
970 #if 0
971                                 if (m_bVegasStyle)
972                                         m_nScore += 5;
973                                 else
974                                         m_nScore += 10;
975 #else
976                                 m_nScore += (m_bVegasStyle ? 5 : 10);
977 #endif
978
979                                 emit UpdateScore(m_nScore);
980                                 break;
981                         }
982                 }
983                 
984                 dcHitStack = hitStack = dcHitDiscard = hitDiscard = false;
985         }
986         else
987                 OnLButtonDown(point); // Either was on draw pile or somewhere else...
988 }
989
990
991 // It's behaving strangely, especially with kings in the ace piles...
992 // It's becuase of the mod 13 function: kings(13) get whacked to 0 this way...
993 void GameWidget::HandleAutoRemove(void)
994 {
995         bool bCheck = true;
996
997         while (bCheck)
998         {
999                 bCheck = false;
1000
1001                 int nLowestAce = (nAce[0] == -1 ? 0 : ((nAce[0] - 1) % 13) + 1); // Aces are 1-based, cards 1-based
1002
1003                 for(int i=1; i<4; i++)
1004                 {
1005                         int nTemp = (nAce[i] == -1 ? 0 : ((nAce[i] - 1) % 13) + 1);
1006
1007                         if (nTemp < nLowestAce)
1008                                 nLowestAce = nTemp;
1009                 }
1010
1011                 for(int i=0; i<7; i++)  // Compare cards that *can* go
1012                 {
1013                         for(int j=18; j>=0; j--)
1014                         {
1015                                 if (solBoard[i][j] != -1)
1016                                 {
1017                                         if (myDeck.IsFaceUp(solBoard[i][j]))
1018                                         {
1019                                                 int nCard = myDeck.GetCardAtPos(solBoard[i][j]);
1020
1021                                                 for(int k=0; k<4; k++)
1022                                                 {
1023                                                         if (IsValidMoveToAce(nAce[k], nCard))
1024                                                         {
1025                                                                 // Ranking/suiting doesn't work if nAce == -1... FIX!
1026                                                                 // Should be fixed now...
1027                                                                 // Figure out some way to simplify this tortuous logic, for cryin' out loud!
1028                                                                 int nSuit[4], nRank[4];
1029
1030                                                                 for(int t=0; t<4; t++)
1031                                                                 {
1032                                                                         if (nAce[t] != -1)
1033                                                                                 nSuit[t] = ((nAce[t] > 13) && (nAce[t] < 40) ? 0 : 1);
1034                                                                         else
1035                                                                                 nSuit[t] = -1;
1036
1037                                                                         nRank[t] = ((nAce[t] - 1) % 13) + 1;
1038                                                                 }
1039
1040                                                                 int nCardSuit = ((nCard > 13) && (nCard < 40) ? 0 : 1),
1041                                                                         nCardRank = ((nCard - 1) % 13) + 1;
1042                                                                 bool bSpecial = false;
1043                                                                 int nCR[2], nCnt = 0;
1044
1045                                                                 for(int t=0; t<4; t++)
1046                                                                         if ((nCardSuit != nSuit[t]) && (t != k) && (nSuit[t] != -1))
1047                                                                                 nCR[nCnt++] = nRank[t];
1048
1049                                                                 if ((nCnt == 2) && (nCR[0] == nCR[1])
1050                                                                         && (nCR[0] - nLowestAce == 2) && (nCardRank - nLowestAce == 3))
1051                                                                         bSpecial = true;
1052
1053                                                                 if (((((nCard - 1) % 13) + 1) - nLowestAce) <= 2 || bSpecial)
1054                                                                 // OR difference is 3 and both opposite color are at 2
1055 //                                                              if (((nCard%13) - nLowestAce) <= 2)
1056                                                                 {
1057                                                                         solBoard[i][j] = -1;
1058
1059                                                                         if (m_bAnimationsOn)
1060                                                                                 AnimateCards(nCard, k, i, j);
1061
1062                                                                         nAce[k] = nCard;
1063                                                                         bCheck = true;
1064
1065                                                                         // Scoring...
1066 #if 0
1067                                                                         if (m_bVegasStyle)
1068                                                                                 m_nScore += 5;
1069                                                                         else
1070                                                                                 m_nScore += 10;
1071 #else
1072                                                                         m_nScore += (m_bVegasStyle ? 5 : 10);
1073 #endif
1074                                                                         emit UpdateScore(m_nScore);
1075                                                                         break;
1076                                                                 }
1077                                                         }
1078                                                 }
1079                                         }
1080
1081                                         break;
1082                                 }
1083                         }
1084                 }
1085
1086                 if (stack2p != -1)
1087                 {
1088                         int nCard = myDeck.GetCardAtPos(stack2[stack2p]);
1089
1090                         for(int k=0; k<4; k++)
1091                         {
1092                                 if (IsValidMoveToAce(nAce[k], nCard))
1093                                 {
1094                                         // Ranking/suiting doesn't work if nAce == -1... FIX!
1095                                         // Should be fixed now...
1096                                         // Figure out some way to simplify this tortuous logic, for cryin' out loud!
1097                                         int nSuit[4], nRank[4];
1098
1099                                         for(int t=0; t<4; t++)
1100                                         {
1101                                                 if (nAce[t] != -1)
1102                                                         nSuit[t] = ((nAce[t] > 13) && (nAce[t] < 40) ? 0 : 1);
1103                                                 else
1104                                                         nSuit[t] = -1;
1105
1106                                                 nRank[t] = ((nAce[t] - 1) % 13) + 1;
1107                                         }
1108
1109                                         int nCardSuit = ((nCard > 13) && (nCard < 40) ? 0 : 1),
1110                                                 nCardRank = ((nCard - 1) % 13) + 1;
1111                                         bool bSpecial = false;
1112                                         int nCR[2], nCnt = 0;
1113
1114                                         for(int t=0; t<4; t++)
1115                                         {
1116                                                 if ((nCardSuit != nSuit[t]) && (t != k) && (nSuit[t] != -1))
1117                                                         nCR[nCnt++] = nRank[t];
1118                                         }
1119
1120                                         if ((nCnt == 2) && (nCR[0] == nCR[1])
1121                                                 && (nCR[0] - nLowestAce == 2) && (nCardRank - nLowestAce == 3))
1122                                                 bSpecial = true;
1123
1124                                         if (((((nCard - 1) % 13) + 1) - nLowestAce) <= 2 || bSpecial)
1125                                         // OR difference is 3 and both opposite color are at 2 (tortuously checked above)
1126                                         {
1127                                                 stack2p--;
1128
1129                                                 if (m_nNumToSplay != 1)
1130                                                         m_nNumToSplay--;
1131
1132                                                 if (m_bAnimationsOn)
1133                                                         AnimateCards(nCard, k, -1, -1);
1134
1135                                                 nAce[k] = nCard;
1136                                                 bCheck = true;
1137
1138                                                 // Scoring...
1139 #if 0
1140                                                 if (m_bVegasStyle)
1141                                                         m_nScore += 5;
1142                                                 else
1143                                                         m_nScore += 10;
1144 #else
1145                                                 m_nScore += (m_bVegasStyle ? 5 : 10);
1146 #endif
1147
1148                                                 emit UpdateScore(m_nScore);
1149                                                 break;
1150                                         }
1151                                 }
1152                         }
1153                 }
1154         }
1155 }
1156
1157
1158 // Have two routines? One to initiate, the other to handle card movements?
1159 // Good idea! Implement it, you schmendrick!
1160 void GameWidget::AnimateCards(int nCard, int nAce, int nTabX, int nTabY)
1161 {
1162 //no mas--jeff no likee CWaitCursor wc;   // Automagically reverts when it goes out of scope
1163         int nCX, nCY, nDX, nDY;
1164
1165         // Step 1: figure out where card started from
1166         if (nTabX == -1)
1167         {
1168 //              nCX = 5+CARD_WIDTH+6, nCY = 5;
1169                 nCX = 5 + CARD_WIDTH + 6 + ((m_nNumToSplay - 1) * 12);
1170                 nCY = 7 + ((m_nNumToSplay - 1) * 2);
1171         }
1172         else
1173         {
1174                 nCX = 10 + (nTabX * (CARD_WIDTH + 8)), nCY = 130;
1175
1176                 for(int j=0; j<nTabY; j++)
1177                 {
1178                         if (solBoard[nTabX][j] != -1)
1179                         {
1180                                 if (myDeck.IsFaceUp(solBoard[nTabX][j]))
1181                                         nCY += 18;
1182                                 else
1183                                         nCY += 4;
1184                         }
1185                 }
1186         }
1187         // Step 2: figure out where card is going
1188         nDX = 200 + ((CARD_WIDTH + 4) * nAce), nDY = 7;
1189         // Step 3: animate card flying from start to destination
1190         // Use Bresenham's algorithm to figure path...
1191         // (ideas for movement: increasing acceleration, curved paths, more than one at a time)
1192         m_bFreeCard = true;
1193         m_pFirstCard = new SCardInfo(nCard);
1194         int nDeltaX = nDX - nCX, nDeltaY = nDY - nCY;
1195         int nError = 0;
1196         int nUpdate = 0;
1197         update(); //will do it??? Seems to...
1198 //Doing this causes an image of the card to be drawn at (0, 0) :-/
1199 //      repaint();
1200         QRect rcOld(nCX, nCY, CARD_WIDTH, CARD_HEIGHT), rcNew, rcUpdate;
1201
1202         if (abs(nDeltaX) > abs(nDeltaY))
1203         {
1204                 for(int i=0; i<abs(nDeltaX); i++)
1205                 {
1206                         // Put card draw stuff into OnDraw? (probably best way to do it...)
1207                         nError += abs(nDeltaY);
1208
1209                         if (nError > abs(nDeltaX))
1210                                 nCY += (nDeltaY < 0 ? -1 : +1), nError -= abs(nDeltaX);
1211
1212                         m_pFirstCard->nXPos = nCX + (nDeltaX < 0 ? -i : +i), m_pFirstCard->nYPos = nCY;
1213                         // Draw card
1214                         nUpdate++;
1215
1216                         if (nUpdate == 10)
1217                         {
1218                                 rcNew = QRect(m_pFirstCard->nXPos, m_pFirstCard->nYPos,
1219                                         CARD_WIDTH, CARD_HEIGHT);
1220                                 rcUpdate = rcOld.united(rcNew);
1221                                 nUpdate = 0;
1222                                 repaint(rcUpdate);
1223                                 rcOld = rcNew;
1224                                 // Pause
1225                                 Pause(3);
1226                         }
1227                         // calc new positions
1228                 }
1229
1230                 m_pFirstCard->nXPos = nDX, m_pFirstCard->nYPos = nDY;
1231                 rcNew = QRect(nDX, nDY, CARD_WIDTH, CARD_HEIGHT);
1232                 rcUpdate = rcOld.united(rcNew);
1233                 repaint(rcUpdate);
1234         }
1235         else
1236         {
1237                 for(int i=0; i<abs(nDeltaY); i++)
1238                 {
1239                         // Put card draw stuff into OnDraw? (probably best way to do it...)
1240                         nError += abs(nDeltaX);
1241
1242                         if (nError > abs(nDeltaY))
1243                                 nCX += (nDeltaX < 0 ? -1 : +1), nError -= abs(nDeltaY);
1244
1245                         m_pFirstCard->nXPos = nCX, m_pFirstCard->nYPos = nCY + (nDeltaY < 0 ? -i : +i);
1246                         // Draw card
1247                         nUpdate++;
1248
1249                         if (nUpdate == 10)
1250                         {
1251                                 rcNew = QRect(m_pFirstCard->nXPos, m_pFirstCard->nYPos,
1252                                         CARD_WIDTH, CARD_HEIGHT);
1253                                 rcUpdate = rcOld.united(rcNew);
1254                                 nUpdate = 0;
1255                                 repaint(rcUpdate);//this is crappy. should only update what's needed!
1256                                 rcOld = rcNew;
1257                                 // Pause
1258                                 Pause(3);
1259                         }
1260                         // calc new positions
1261                 }
1262
1263                 m_pFirstCard->nXPos = nDX, m_pFirstCard->nYPos = nDY;
1264                 rcNew = QRect(nDX, nDY, CARD_WIDTH, CARD_HEIGHT);
1265                 rcUpdate = rcOld.united(rcNew);
1266                 repaint(rcUpdate);
1267         }
1268
1269         m_bFreeCard = false;
1270         delete m_pFirstCard;
1271 }
1272
1273
1274 bool GameWidget::IsValidMoveToAce(int nAceM)
1275 {
1276         int nCards = 0;
1277
1278         for(int k=stackStart.y(); k<19; k++)
1279         {
1280                 if (solBoard[stackStart.x()][k] != -1)
1281                         nCards++;
1282         }
1283
1284         if ((hitStack && (nCards == 1)) || hitDiscard)
1285         {
1286                 int nCardHit = (hitStack ? myDeck.GetCardAtPos(solBoard[stackStart.x()][stackStart.y()])
1287                         : myDeck.GetCardAtPos(stack2[stack2p]));
1288                 return IsValidMoveToAce(nAceM, nCardHit);
1289         }
1290         else if (nHitAce != 0)
1291         {
1292                 return IsValidMoveToAce(nAceM, nAce[nHitAce - 1]);
1293         }
1294
1295         return false;
1296 }
1297
1298
1299 bool GameWidget::IsValidMoveToAce(int nAce, int nCard)
1300 {
1301         if (((nAce == -1) && ((nCard % 13) == 1))
1302                 || ((nAce == (nCard - 1)) && ((nAce % 13) != 0)))
1303                 return true;
1304
1305         return false;
1306 }
1307
1308
1309 bool GameWidget::IsValidMoveToTableaux(int nStack)
1310 {
1311         int nBottomCard = -1, nTopCard;
1312
1313         for(int i=0; i<19; i++)
1314         {
1315                 if ((solBoard[nStack][i] != -1) && (myDeck.IsFaceUp(solBoard[nStack][i])))
1316                         nBottomCard = myDeck.GetCardAtPos(solBoard[nStack][i]);
1317         }
1318
1319         if (hitStack)
1320                 nTopCard = myDeck.GetCardAtPos(solBoard[stackStart.x()][stackStart.y()]);
1321         else if (hitDiscard)
1322                 nTopCard = myDeck.GetCardAtPos(stack2[stack2p]);
1323         else if (nHitAce != 0)
1324                 nTopCard = nAce[nHitAce - 1];
1325
1326         int colorBC = ((nBottomCard > 13) && (nBottomCard < 40) ? 0 : 1);
1327         int colorTC = ((nTopCard > 13) && (nTopCard < 40) ? 0 : 1);
1328         int rankBC = (nBottomCard - 1) % 13;
1329         int rankTC = (nTopCard - 1) % 13;
1330
1331         if (((rankBC == (rankTC + 1)) && (colorBC != colorTC))
1332                 || ((nBottomCard == -1) && (rankTC == 12)))
1333                 return true;
1334         
1335         return false;
1336 }
1337
1338
1339 bool GameWidget::PlayerWon(void)
1340 {
1341         for(int i=0; i<7; i++)
1342                 if (solBoard[i][0] != -1)
1343                   return false;
1344
1345         if ((stack1p != -1) || (stack2p != -1))
1346                 return false;
1347
1348         return true;
1349 }
1350
1351
1352 void GameWidget::HandleStatistics(void)
1353 {
1354         if (PlayerWon())
1355         {
1356                 m_nWins++;
1357
1358                 if (m_bWonLastGame)
1359                         m_nStreakC++;
1360                 else
1361                         m_nStreakC = 1;
1362         }
1363         else
1364         {
1365                 m_nLosses++;
1366
1367                 if (!m_bWonLastGame)
1368                         m_nStreakC--;
1369                 else
1370                         m_nStreakC = -1;
1371         }
1372
1373         if (m_nStreakC < 0)    // Beat largest losing streak?
1374         {
1375                 if (abs(m_nStreakC) > m_nStreakL)
1376                         m_nStreakL = abs(m_nStreakC);
1377         }
1378         else                   // Check for longest winning streak
1379         {
1380                 if (m_nStreakC > m_nStreakW)
1381                         m_nStreakW = m_nStreakC;
1382         }
1383
1384         if (m_bVegasStyle)     // Check for high score
1385         {
1386                 if (m_nScore > m_nVHiScore)
1387                         m_nVHiScore = m_nScore;
1388         }
1389         else
1390         {
1391                 if (m_nScore > m_nHiScore)
1392                         m_nHiScore = m_nScore;
1393         }
1394 }
1395 #endif
1396
1397
1398 //
1399 // Halt processing for 'count' milliseconds
1400 //
1401 void GameWidget::Pause(int count)
1402 {
1403 //      DWORD endCount = GetTickCount() + count;
1404 //      while (GetTickCount() < endCount) {}     // Still crude, but better control
1405 #if 1
1406         usleep(count * 1000);
1407 #else
1408         // This causes it to lock up randomly. :-/
1409         QTime time;
1410         time.start();
1411
1412         while (time.msec() < count)
1413                 ; // Do nothing...
1414 #endif
1415 }
1416