]> Shamusworld >> Repos - warehouse-man-deluxe/blob - src/mainwin.cpp
010f27f7d63f78ab6652bfd87743b3f5c4d4d8f4
[warehouse-man-deluxe] / src / mainwin.cpp
1 //
2 // mainwin.cpp: Implementation of the MainWin class
3 //
4 //   JLH = James Hammons <jlhamm@acm.org>
5 //
6 // Who  When        What
7 // ---  ----------  ------------------------------------------------------------
8 // JLH  03/01/2014  Created this file
9 //
10
11 // TO DO:
12 //
13
14 #include "mainwin.h"
15
16 #include <stdlib.h>                     // For rand()
17 #include <time.h>                       // For time()
18 #include "gameboard.h"
19 #include "gamewidget.h"         // Actual mouse/drawing window
20 //#include "resource.h"
21 //#include "optiondlg.h"                // Options dialog class
22 //#include "statdlg.h"          // Statistics dialog class
23
24
25 MainWin::MainWin()
26 {
27         gameWidget = new GameWidget(this);
28         setCentralWidget(gameWidget);
29         gameWidget->setFocusPolicy(Qt::StrongFocus);    // Without this, it gets no keys
30         setWindowTitle("Warehouse Man Deluxe");
31         setWindowIcon(QIcon(":/wmd-icon.png"));
32
33         newGame = CreateAction(tr("&New"), tr("New Game"), tr("Start a new game of Warehouse Man Deluxe"), QIcon(), QKeySequence(tr("ctrl+n")));
34 //      connect(newGame, SIGNAL(triggered()), this, SLOT(OnNewGame()));
35
36         undoAction = CreateAction(tr("&Undo"), tr(""), tr(""), QIcon(), QKeySequence(tr("ctrl+z")));
37         connect(undoAction, SIGNAL(triggered()), this, SLOT(HandleUndo()));
38
39         resetLevel = CreateAction(tr("&Reset Level"), tr("Reset Level"), tr("Start the current level over"), QIcon(), QKeySequence(tr("ctrl+r")));
40         connect(resetLevel, SIGNAL(triggered()), this, SLOT(HandleReset()));
41
42         skipLevel = CreateAction(tr("&Skip Level"), tr("Skip Level"), tr("Skip the current level"), QIcon(), QKeySequence(tr("ctrl+k")));
43         connect(skipLevel, SIGNAL(triggered()), this, SLOT(HandleSkipLevel()));
44
45         gameOptions = CreateAction(tr("&Options..."), tr("Options"), tr("Configure Warehouse Man Deluxe's options"), QIcon(), QKeySequence(tr("ctrl+o")));
46 //      connect(gameOptions, SIGNAL(triggered()), this, SLOT(OnGameOptions()));
47
48         gameStats = CreateAction(tr("&Stats..."), tr("Game Stats"), tr("Show game stats"), QIcon(), QKeySequence(tr("ctrl+s")));
49 //      connect(gameStats, SIGNAL(triggered()), this, SLOT(OnGameStats()));
50
51         appExit = CreateAction(tr("E&xit"), tr("Exit"), tr("Quit playing Warehouse Man Deluxe..."), QIcon(), QKeySequence(tr("ctrl+q")));
52         connect(appExit, SIGNAL(triggered()), this, SLOT(close()));
53
54         appAbout = CreateAction(tr("&About"), tr("About"), tr("Display program information..."), QIcon(), QKeySequence(tr("")));
55         connect(appAbout, SIGNAL(triggered()), this, SLOT(AboutGame()));
56
57         // Get signals from the gameboard to update scores...
58 //      connect(gameBoard, SIGNAL(UpdateScore(int)), this, SLOT(OnUpdateScore(int)));
59         connect(gameWidget, SIGNAL(GameWasWon()), this, SLOT(WeHaveAWinner()));
60
61         QMenu * menu = menuBar()->addMenu(tr("&Game"));
62         menu->addAction(newGame);
63         menu->addSeparator();
64 //      menu->addAction(gamePlay);
65         menu->addAction(undoAction);
66         menu->addAction(resetLevel);
67         menu->addAction(skipLevel);
68         menu->addSeparator();
69         menu->addAction(gameOptions);
70         menu->addAction(gameStats);
71         menu->addSeparator();
72         menu->addAction(appExit);
73
74         menu = menuBar()->addMenu(tr("&Help"));
75         menu->addAction(appAbout);
76
77 //      statusBar()->addPermanentWidget(gameBoard->score);
78         statusBar()->showMessage(tr("Ready"));
79
80         QSettings settings("Underground Software", "Warehouse Man Deluxe");
81         QPoint mainWinPosition = settings.value("pos", QPoint(200, 100)).toPoint();
82         move(mainWinPosition);
83         QSize mainWinSize = settings.value("size", QSize(500, 500)).toSize();
84         resize(mainWinSize);
85
86 /*      nCardBack = settings.value("CardBack", BACK4).toInt();
87         m_nBackground = settings.value("Background", 0).toInt();
88         bSoundOn = settings.value("EnableSound", true).toBool();
89         m_bAnimationsOn = settings.value("EnableAnimations", true).toBool();
90         bAutoRemove = settings.value("AutoRemove", true).toBool();
91         scoringOn = settings.value("EnableScoring", false).toBool();
92         m_bCumulativeOn = settings.value("CumulativeScore", false).toBool();
93         m_bVegasStyle = settings.value("VegasScoring", false).toBool();
94         m_bDrawThree = settings.value("DrawThree", false).toBool();
95         m_nWins = settings.value("NumWins", 0).toInt();
96         m_nLosses = settings.value("NumLosses", 0).toInt();
97         m_nHiScore = settings.value("HiScore", 0).toInt();
98         m_nVHiScore = settings.value("VegasHiScore", 0).toInt();
99         m_nStreakW = settings.value("WinStreak", 0).toInt();
100         m_nStreakL = settings.value("LoseStreak", 0).toInt();
101         m_nStreakC = settings.value("CurrentStreak", 0).toInt();
102         m_bWonLastGame = settings.value("WonLastGame", false).toBool();
103         m_nScore = settings.value("LastScore", -52).toInt();*/
104
105 //      gameBoard->CreateBackground();
106 //      InitializeAudio();
107
108 //      mouseDown = false;
109 //      myDeck.SetCardWidth(CARD_WIDTH);
110 //      myDeck.SetCardHeight(CARD_HEIGHT);
111 //
112 //      for(int i=0; i<52; i++)
113 //              myDeck.SetCardPosition(i, QPoint(0, 0));
114
115         ResetGame();
116 //      allowUserInput = true;
117 //      m_bFreeCard = false;
118 //      m_pFirstCard = NULL;
119 }
120
121
122 MainWin::~MainWin()
123 {
124 //      ShutDownAudio();
125 }
126
127
128 //
129 // Consolidates action creation from a multi-step process to a single-step one.
130 //
131 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
132         QIcon icon, QKeySequence key, bool checkable/*= false*/)
133 {
134         QAction * action = new QAction(icon, name, this);
135         action->setToolTip(tooltip);
136         action->setStatusTip(statustip);
137         action->setShortcut(key);
138         action->setCheckable(checkable);
139
140         return action;
141 }
142
143
144 //
145 // This is essentially the same as the previous function, but this allows more
146 // than one key sequence to be added as key shortcuts.
147 //
148 QAction * MainWin::CreateAction(QString name, QString tooltip, QString statustip,
149         QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
150 {
151         QAction * action = new QAction(icon, name, this);
152         action->setToolTip(tooltip);
153         action->setStatusTip(statustip);
154         QList<QKeySequence> keyList;
155         keyList.append(key1);
156         keyList.append(key2);
157         action->setShortcuts(keyList);
158         action->setCheckable(checkable);
159
160         return action;
161 }
162
163
164 void MainWin::closeEvent(QCloseEvent * event)
165 {
166 /*      if (allowUserInput && m_bTouchedGame)
167         {
168                 gameBoard->HandleStatistics();
169                 m_bWonLastGame = false;
170         }*/
171
172         QSettings settings("Underground Software", "Warehouse Man Deluxe");
173         settings.setValue("pos", pos());
174         settings.setValue("size", size());
175
176 /*
177         settings.setValue("CardBack", nCardBack);
178         settings.setValue("Background", m_nBackground);
179         settings.setValue("EnableSound", bSoundOn);
180         settings.setValue("EnableAnimations", m_bAnimationsOn);
181         settings.setValue("AutoRemove", bAutoRemove);
182         settings.setValue("EnableScoring", scoringOn);
183         settings.setValue("CumulativeScore", m_bCumulativeOn);
184         settings.setValue("VegasScoring", m_bVegasStyle);
185         settings.setValue("DrawThree", m_bDrawThree);
186         settings.setValue("NumWins", m_nWins);
187         settings.setValue("NumLosses", m_nLosses);
188         settings.setValue("HiScore", m_nHiScore);
189         settings.setValue("VegasHiScore", m_nVHiScore);
190         settings.setValue("WinStreak", m_nStreakW);
191         settings.setValue("LoseStreak", m_nStreakL);
192         settings.setValue("CurrentStreak", m_nStreakC);
193         settings.setValue("WonLastGame", m_bWonLastGame);
194         settings.setValue("LastScore", m_nScore);*/
195
196         event->accept();
197 }
198
199
200 /*
201 void MainWin::OnUpdateScore(int n)
202 {
203         if (!scoringOn)
204                 return;
205
206         QString s;
207
208         if (m_bVegasStyle)
209                 s = QString(tr("Score: $%1")).arg(n);
210         else
211                 s = QString(tr("Score: %1")).arg(n);
212
213         gameBoard->score->setText(s);
214 printf("OUS: n=%i, s=%s\n", n, s.toAscii().data());
215 }
216 */
217
218 void MainWin::ResetGame(void)
219 {
220         gameWidget->level = 1;
221
222 /*      myDeck.Shuffle();
223
224         for(int i=0; i<7; i++)
225                 for(int j=0; j<20; j++)
226                         solBoard[i][j] = -1; // Empty the board...
227
228         int card = 0;
229         myDeck.SetAllFaceDown();
230
231         for(int i=0; i<7; i++)       // Fill the tableaux
232         {
233                 for(int j=i; j<7; j++)
234                 {
235                         solBoard[6 - i][6 - j] = card;
236
237                         if (i == j)
238                                 myDeck.SetCardFaceUp(card);
239
240                         card++;
241                 }
242         }
243
244         for(int i=0; i<24; i++)   // Fill the stack
245                 stack1[i] = card++;
246
247         stack1p = 23;
248         stack2p = -1;
249         nAce[0] = nAce[1] = nAce[2] = nAce[3] = -1;
250
251         hitStack = hitDiscard = false;
252         nHitAce = 0;
253         m_bTouchedGame = false;
254
255         if (!m_bVegasStyle)
256                 m_nScore = 0;
257         else
258         {
259                 if (!m_bCumulativeOn)
260                         m_nScore = -52;
261                 else
262                         m_nScore -= 52;
263         }
264
265         m_nExhaustedDeck = 0;
266         m_bShowX = false;
267         m_bCanUndo = false;
268
269         OnUpdateScore(m_nScore);*/
270 }
271
272
273 void MainWin::AboutGame(void)
274 {
275         QMessageBox::about(this, tr("About Warehouse Man Deluxe"), tr("Warehouse Man Deluxe Version 1.0\n\nCopyright (C) 2014 Underground Software\n\nWritten by James L. Hammons"));
276 }
277
278
279 void MainWin::WeHaveAWinner(void)
280 {
281         QMessageBox::information(this, "Warehouse Man Deluxe", "Congratulations!\nYou beat this level!\nNow try the next level!");
282         gameWidget->NextLevel();
283 }
284
285
286 void MainWin::HandleReset(void)
287 {
288         gameWidget->ResetLevel();
289 }
290
291
292 void MainWin::HandleSkipLevel(void)
293 {
294         gameWidget->NextLevel();
295 }
296
297
298 void MainWin::HandleUndo(void)
299 {
300         gameWidget->UndoLastMove();
301 }
302
303
304 #if 0
305 void MainWin::OnNewGame(void) 
306 {
307         if (allowUserInput && m_bTouchedGame)   // Player didn't win...
308         {
309                 gameBoard->HandleStatistics();
310                 m_bWonLastGame = false;
311         }
312
313         ResetGame();
314         gameBoard->update();
315         allowUserInput = true;
316
317 #if HAVE_SOUND
318         if (bSoundOn)
319         {
320                 PlaySound(IDW_CARDKNOCK);
321                 gameBoard->Pause(300);
322                 PlaySound(IDW_SHUFFLE);
323         }
324 #endif
325 }
326
327
328 void MainWin::OnGameOptions(void)
329 {
330         OptionDlg dlg;
331
332         dlg.m_cardBack = nCardBack - BACK1;
333         dlg.m_nBackground = m_nBackground;
334         dlg.m_bCheck1 = bSoundOn;
335         dlg.m_bCheck2 = m_bAnimationsOn;
336         dlg.m_bCheck3 = bAutoRemove;
337         dlg.m_bCheck4 = scoringOn;
338         dlg.m_bCheck5 = m_bCumulativeOn;
339         dlg.m_nRadio1 = m_bVegasStyle;
340         dlg.m_nRadio3 = m_bDrawThree;
341
342         dlg.UpdateUI();
343
344         if (dlg.exec() == QDialog::Rejected)
345                 return;
346
347         dlg.UpdateData();
348
349         nCardBack = dlg.m_cardBack + BACK1;
350         m_nBackground = dlg.m_nBackground;
351         bSoundOn = (bool)dlg.m_bCheck1;
352         m_bAnimationsOn = (bool)dlg.m_bCheck2;
353         bAutoRemove = (bool)dlg.m_bCheck3;
354         m_bCumulativeOn = (bool)dlg.m_bCheck5;
355
356         // Reset game if Vegas Style/Draw Three changes at all...
357         bool bChanged =  (bool)((m_bVegasStyle != (bool)dlg.m_nRadio1)
358                 || (m_bDrawThree != (bool)dlg.m_nRadio3) || (scoringOn != (bool)dlg.m_bCheck4));
359
360         scoringOn = (bool)dlg.m_bCheck4;
361         m_bVegasStyle = (bool)dlg.m_nRadio1;
362         m_bDrawThree = (bool)dlg.m_nRadio3;
363
364         if (bChanged && m_bTouchedGame)
365                 OnNewGame();  // Probably should warn of this...
366
367         gameBoard->CreateBackground();
368         gameBoard->update();
369 }
370
371
372 void MainWin::OnGameStats(void)
373 {
374         StatDlg dlg;
375
376 /*      dlg.m_nWins = m_nWins;
377         dlg.m_nLosses = m_nLosses;
378         dlg.m_nHiScore = m_nHiScore;
379         dlg.m_nVHiScore = m_nVHiScore;
380         dlg.m_nStreakW = m_nStreakW;
381         dlg.m_nStreakL = m_nStreakL;
382         dlg.m_nStreakC = m_nStreakC;*/
383
384         dlg.exec();
385
386         // Since it's possible to reset the stats, we grab the fields back here...
387 /*      m_nWins = dlg.m_nWins;
388         m_nLosses = dlg.m_nLosses;
389         m_nHiScore = dlg.m_nHiScore;
390         m_nVHiScore = dlg.m_nVHiScore;
391         m_nStreakW = dlg.m_nStreakW;
392         m_nStreakL = dlg.m_nStreakL;
393         m_nStreakC = dlg.m_nStreakC;*/
394 }
395
396
397 void MainWin::OnundoAction(void)
398 {
399         if (m_bCanUndo)
400         {
401                 for(int i=0; i<7; i++)
402                         for(int j=0; j<20; j++)
403                                 solBoard[i][j] = solBoardUndo[i][j];
404
405                 for(int i=0; i<24; i++)
406                         stack1[i] = stack1Undo[i], stack2[i] = stack2Undo[i];
407
408                 for(int i=0; i<4; i++)
409                         nAce[i] = nAceUndo[i];
410
411                 stack1p = stack1pUndo, stack2p = stack2pUndo;
412                 m_nScore = m_nScoreUndo;
413                 m_nExhaustedDeck = m_nExhaustedDeckUndo;
414                 m_nNumToSplay = m_nNumToSplayUndo;
415                 m_bShowX = m_bShowXUndo;
416
417                 OnUpdateScore(m_nScore);
418         }
419
420         m_bCanUndo = false;
421         gameBoard->update();  // wil wok?
422 }
423
424
425 void MainWin::OnGamePlay(void)
426 {
427         // Play a card from discard deck...
428         //NOTE: can reduce size by eliminating duplicate code in OnLButtonDown...
429         m_bCanUndo = true;
430
431         if (stack1p == -1)  // I.e. it's empty...
432         {
433                 // Scoring...
434                 if ((m_bDrawThree && (m_nExhaustedDeck == 3))
435                         || (!m_bDrawThree && (m_nExhaustedDeck == 1)))
436                 {
437                         if (!m_bVegasStyle)
438                         {
439                                 m_nExhaustedDeck = 0;
440                                 m_nScore -= (m_bDrawThree ? 20 : 100);
441
442                                 if (m_nScore < 0)
443                                         m_nScore = 0;
444
445                                 OnUpdateScore(m_nScore);
446                         }
447                 }
448
449                 if (!m_bVegasStyle || (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck < 3))
450                                 || (!m_bDrawThree && (m_nExhaustedDeck < 1)))))
451                 {
452                         for(; stack2p!=-1; stack2p--)
453                                 stack1[++stack1p] = stack2[stack2p];
454
455 #if HAVE_SOUND
456                         if (bSoundOn)
457                                 PlaySound(IDW_CARDKNOCK);
458 #endif
459                 }
460         }
461         else
462         {
463                 m_nNumToSplay = 0;
464
465                 for(int i=0; i<(m_bDrawThree ? 3 : 1); i++)
466                 {
467                         if (stack1p != -1)  // I.e., there are cards left...
468                         {
469                                 stack2[++stack2p] = stack1[stack1p--];
470
471 #if HAVE_SOUND
472                                 if (bSoundOn)
473                                 {
474                                         PlaySound(IDW_CARDFLIP);
475                                         // Pause
476                                         gameBoard->Pause(55);
477                                 }
478 #endif
479
480                                 m_nNumToSplay++;
481                         }
482                 }
483
484                 if (stack1p == -1)  // This is done here because it's right!
485                 {
486                         m_nExhaustedDeck++;
487
488                         if (m_bVegasStyle && ((m_bDrawThree && (m_nExhaustedDeck == 3))
489                                 || (!m_bDrawThree && (m_nExhaustedDeck == 1))))
490                                 m_bShowX = true;
491                 }
492         }
493
494         if (bAutoRemove)
495                 gameBoard->HandleAutoRemove();
496
497         gameBoard->update();
498 }
499
500
501 #endif
502