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