Files
2026-02-02 04:50:13 +01:00

1743 lines
52 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/boflib/misc.h"
#include "bagel/hodjnpodj/hnplibs/stdafx.h"
#include "bagel/hodjnpodj/wordsearch/wordsearch.h"
#include "bagel/hodjnpodj/wordsearch/dialogs.h"
#include "bagel/hodjnpodj/wordsearch/wordlist.h"
#include "bagel/hodjnpodj/wordsearch/clongdlg.h"
#include "bagel/hodjnpodj/hodjnpodj.h"
namespace Bagel {
namespace HodjNPodj {
namespace WordSearch {
extern CMainWSWindow *pMainGameWnd;
extern HCURSOR hGameCursor;
extern void PlayEasterEgg(CDC *pDC, CWnd *pWnd, CPalette *pPalette,
const char *pszAnimFile, const char *pszSoundFile,
int nNumCels, int nXLoc, int nYLoc, int nSleep, bool bPlaySound);
CPalette *pGamePalette = nullptr; // Palette to be used throughout the game
CBmpButton *pOptionButton = nullptr; // Option button object for getting to the options dialog
char acWordChosen[WORDSPERLIST];
char acWordBack[WORDSPERLIST];
POINT ptCurrPosInGrid;
POINT ptLastPosInGrid;
POINT ptOrigPosInGrid;
bool bResetGame;
CDC *pOffScreenDC = nullptr;
CPalette *pOldOffScreenPal = nullptr;
CBitmap *pOffScreenBmp = nullptr;
CBitmap *pOldOffScreenBmp = nullptr;
CBitmap *pbmpSplashScreen = nullptr;
CBitmap *pbmpAllLetters;
int nCurrentLetter;
CText *ptxtScore = nullptr;
CString *astrGameList[WORDSPERLIST];
CString *astrGameListDisplay[WORDSPERLIST];
CText *atxtDisplayWord[WORDSPERLIST];
static CSound *pGameSound = nullptr; // Game theme song
CSprite *pTimerSprite = nullptr;
int nLastCell;
unsigned int nTimerRes;
long lCurrentTimer;
int nWordsLeft;
int nWordList;
char acAlpha[26] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
};
extern const char *astrWLCat[NUMBEROFLISTS];
extern char acList[NUMBEROFLISTS][WORDSPERLIST][20];
/*****************************************************************
*
* CMainWSWindow
*
* FUNCTIONAL DESCRIPTION:
*
* Create the window with the appropriate style, size, menu, etc.;
* it will be later revealed by CTheApp::InitInstance(). Then
* create our splash screen object by opening and loading its DIB.
*
* FORMAL PARAMETERS:
*
* lUserAmount = initial amount of money that user starts with
* defaults to zero
* nRounds = the number of rounds to play, if 0 then not playing rounds
* = defaults to zero
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
CMainWSWindow::CMainWSWindow(HWND hCallingWnd, LPGAMESTRUCT lpGameStruct) :
rNewGame(21, 3, 227, 20),
rRefreshRect(0, 0, GAME_WIDTH, 385),
rScore(190, 340, 610, 365) {
CDC *pDC = nullptr; // device context for the screen
CString WndClass;
CSize mySize;
bool bTestCreate; // bool for testing the creation of each button
int x, y;
CText atxtDisplayRow[NUMBEROFROWS];
BeginWaitCursor();
CPalette *pOldPal = nullptr;
// Define a special window class which traps double-clicks, is byte aligned
// to maximize BITBLT performance, and creates "owned" DCs rather than sharing
// the five system defined DCs which are not guaranteed to be available;
// this adds a bit to our app size but avoids hangs/freezes/lockups.
WndClass = AfxRegisterWndClass(CS_DBLCLKS | CS_BYTEALIGNWINDOW | CS_OWNDC,
hGameCursor, nullptr, nullptr);
// set the seed for the random number generator
//srand( (unsigned)time( nullptr ));
// initialize private members
m_lpGameStruct = lpGameStruct;
m_lpGameStruct->lScore = (WORDSPERLIST);
m_hCallAppWnd = hCallingWnd;
m_bWordsForwardOnly = false;
// Initialize globals to point to class fields
for (int i = 0; i < WORDSPERLIST; ++i) {
astrGameList[i] = &_strGameList[i];
astrGameListDisplay[i] = &_strGameListDisplay[i];
atxtDisplayWord[i] = &_txtDisplayWord[i];
}
// load splash screen
pDC = GetDC(); // get a device context for our window
pbmpSplashScreen = FetchBitmap(pDC, &pGamePalette, SPLASHSPEC); // get splash screen and game palettte
pOldPal = pDC->SelectPalette(pGamePalette, false); // load game palette
pDC->RealizePalette(); // realize game palette
// set window coordinates to center game on screeen
MainRect.left = (pDC->GetDeviceCaps(HORZRES) - GAME_WIDTH) >> 1;
MainRect.top = (pDC->GetDeviceCaps(VERTRES) - GAME_HEIGHT) >> 1;
MainRect.right = MainRect.left + GAME_WIDTH; // determine where to place the game window
MainRect.bottom = MainRect.top + GAME_HEIGHT; // ... so it is centered on the screen
pDC->SelectPalette(pOldPal, false); // replace old palette
ReleaseDC(pDC); // release our window context
// Create the window as a POPUP so that no boarders, title, or menu are present;
// this is because the game's background art will fill the entire 640x40 area.
Create(WndClass, "Boffo Games - Word Search", WS_POPUP, MainRect, nullptr, 0);
pDC = GetDC();
pOldPal = pDC->SelectPalette(pGamePalette, false); // load game palette
pDC->RealizePalette(); // realize game palette
pOptionButton = new CBmpButton; // create the Options button
ASSERT(pOptionButton != 0);
OptionRect.SetRect(OPTION_LEFT,
OPTION_TOP,
OPTION_LEFT + OPTION_WIDTH,
OPTION_TOP + OPTION_HEIGHT);
bTestCreate = pOptionButton->Create("Options", BS_OWNERDRAW | WS_CHILD | WS_VISIBLE, OptionRect, this, IDC_OPTION);
ASSERT(bTestCreate != 0); // test for button's creation
bTestCreate = pOptionButton->LoadBitmaps(SCROLLUP, SCROLLDOWN, SCROLLUP, SCROLLUP);
ASSERT(bTestCreate != 0); // test for button's creation
ShowWindow(SW_SHOWNORMAL);
PaintBitmap(pDC, pGamePalette, pbmpSplashScreen, 0, 0, GAME_WIDTH, GAME_HEIGHT);
pOffScreenBmp = new CBitmap();
pOffScreenDC = new CDC();
pOffScreenBmp->CreateCompatibleBitmap(pDC, GAME_WIDTH, GAME_HEIGHT); // create offscreen bitmap
pOffScreenDC->CreateCompatibleDC(pDC); // create offscreen DC
pOldOffScreenPal = pOffScreenDC->SelectPalette(pGamePalette, false); // load in game palette
pOldOffScreenBmp = pOffScreenDC->SelectObject(pOffScreenBmp); // load in offscreen bitmap
pOffScreenDC->RealizePalette(); // realize palette
//pbmpAllLetters = FetchBitmap( pDC, nullptr, ALLLETTERS );
pbmpAllLetters = FetchBitmap(pOffScreenDC, nullptr, ALLLETTERS);
ASSERT(pbmpAllLetters != 0);
ptxtScore = new CText(pOffScreenDC, pGamePalette, &rScore, JUSTIFY_CENTER);
pTimerSprite = new CSprite;
pTimerSprite->SharePalette(pGamePalette);
bTestCreate = pTimerSprite->LoadCels(pDC, TIMERSPRITE, TIMERSPRITECELS);
ASSERT(bTestCreate); // test for sprite's creation
pTimerSprite->SetPosition(FLOWER_X, FLOWER_Y);
pTimerSprite->SetMasked(true);
pTimerSprite->SetMobile(false);
for (y = 0; y < WORDSPERLIST; y++) {
arWordDisplay[y].SetRect(20, 50 + (y * 15), 170, 50 + (y * 15) + 14);
_txtDisplayWord[y].SetupText(pOffScreenDC, pGamePalette, &arWordDisplay[y], JUSTIFY_RIGHT);
}
// paint splash screen to offscreen DC
PaintBitmap(pOffScreenDC, pGamePalette, pbmpSplashScreen, 0, 0, GAME_WIDTH, GAME_HEIGHT);
pDC->SelectPalette(pOldPal, false); // replace old palette
ReleaseDC(pDC); // release our window context
for (y = 0; y < NUMBEROFROWS; y++) {
for (x = 0; x < NUMBEROFCOLS; x++) {
arScreenGrid[y][x].SetRect(190 + (x * 21), 40 + (y * 21),
190 + (x * 21) + 20, 40 + (y * 21) + 21);
}
}
if (m_lpGameStruct->bPlayingMetagame == true) {
pDC = GetDC();
m_bShowWordList = false;
if (m_lpGameStruct->nSkillLevel == SKILLLEVEL_LOW) {
m_nTimeForGame = 75;
m_bWordsForwardOnly = true;
}
if (m_lpGameStruct->nSkillLevel == SKILLLEVEL_MEDIUM) {
m_nTimeForGame = 60;
m_bWordsForwardOnly = true;
}
if (m_lpGameStruct->nSkillLevel == SKILLLEVEL_HIGH) {
m_nTimeForGame = 60;
m_bWordsForwardOnly = false;
}
// SetTimer( GAMETIMER, nTimerRes, nullptr );
long lTemp = (long)m_nTimeForGame * 1000;
// nTimerRes = (unsigned int)( lTemp / ( TIMERSPRITECELS - 1) );
nTimerRes = (unsigned int)(lTemp / (TIMERSPRITECELS - 2));
nLastCell = -1;
pTimerSprite->SetCel(nLastCell);
ReleaseDC(pDC);
} else {
m_nTimeForGame = 300;
// nTimerRes = (unsigned int)( (m_nTimeForGame * 1000) / ( TIMERSPRITECELS - 1) );
nTimerRes = (unsigned int)((m_nTimeForGame * 1000) / (TIMERSPRITECELS - 2));
nLastCell = -1;
m_bShowWordList = true;
m_bWordsForwardOnly = false;
}
//CreateNewGrid();
//SetWindowPos( &wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
// create buttons
m_bMouseCaptured = false;
bResetGame = false;
lCurrentTimer = 1;
nWordsLeft = WORDSPERLIST;
if (m_lpGameStruct->bMusicEnabled) {
pGameSound = new CSound(this, GAME_THEME,
SOUND_MIDI | SOUND_LOOP | SOUND_DONT_LOOP_TO_END);
(*pGameSound).midiLoopPlaySegment(500, 31500, 0, FMT_MILLISEC);
} // end if pGameSound
EndWaitCursor();
if (m_lpGameStruct->bPlayingMetagame) {
CreateNewGrid();
SplashScreen();
SetTimer(GAMETIMER, nTimerRes, nullptr);
}
}
/*****************************************************************
*
* OnPaint
*
* FUNCTIONAL DESCRIPTION:
*
* Repaint the screen whenever needed; e.g. when uncovered by an
* overlapping window, when maximized from an icon, and when it the
* window is initially created. Ensures that the entire client area
* of the main screen window is repainted, not just the portion in the
* update region; see SplashScreen();
*
* This routine is called whenever Windows sends a WM_PAINT message.
* Note that creating a CPaintDC automatically does a BeginPaint and
* an EndPaint call is done when it is destroyed at the end of this
* function. CPaintDC's constructor needs the window (this).
*
* FORMAL PARAMETERS:
*
* n/a
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
void CMainWSWindow::OnPaint() {
PAINTSTRUCT lpPaint;
BeginPaint(&lpPaint); // bracket start of window update
SplashScreen(); // repaint our window's content
EndPaint(&lpPaint); // bracket end of window update
}
/*****************************************************************
*
* SplashScreen
*
* FUNCTIONAL DESCRIPTION:
*
* Repaint the background artwork, together with all sprites in the
* sprite chain queue. The entire window is redrawn, rather than just
* the updated area, to ensure that the sprites end up with the correct
* background bitmaps saved for their image areas.
*
* FORMAL PARAMETERS:
*
* n/a
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
void CMainWSWindow::SplashScreen() {
CPalette *pOldPalette;
CDC *pDC = GetDC(); // get a device context for the window
ASSERT(pDC);
pOldPalette = pDC->SelectPalette(pGamePalette, false); // load game palette
pDC->RealizePalette(); // realize game palette
pTimerSprite->SetCel(nLastCell);
pTimerSprite->PaintSprite(pOffScreenDC, FLOWER_X, FLOWER_Y);
pDC->BitBlt(0, 0, GAME_WIDTH, GAME_HEIGHT, pOffScreenDC, 0, 0, SRCCOPY); // Draw Word grid from offscreen
pDC->SelectPalette(pOldPalette, false); // replace old palette
ReleaseDC(pDC); // release the window's context
}
/*****************************************************************
*
* ResetGame
*
* FUNCTIONAL DESCRIPTION:
*
* Start a new game, and reset all arrays and buttons
*
* FORMAL PARAMETERS:
*
* n/a
*
* IMPLICIT INPUT PARAMETERS:
*
* aDealtArray, apHold
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
void CMainWSWindow::ResetGame() {
CDC *pDC;
pDC = GetDC();
nLastCell = -1;
KillTimer(GAMETIMER);
lCurrentTimer = 1;
CreateNewGrid();
SplashScreen();
if (m_nTimeForGame > 0) {
long lTemp = (long)m_nTimeForGame * 1000;
nTimerRes = (unsigned int)(lTemp / (TIMERSPRITECELS - 2));
SetTimer(GAMETIMER, nTimerRes, nullptr);
}
ReleaseDC(pDC);
return;
}
void CMainWSWindow::CreateNewGrid() {
int x, y, z;
POINT ptSPos;
int nDirection;
char cSpace = ' ';
char cTemp1[21];
char cTemp2[21];
bool bTemp1;
bool bTemp2;
int nWordLen;
CText atxtDisplayRow[NUMBEROFROWS];
CString strTemp;
int nIterations1 = 0;
int nIterations2;
CRect rDisplayCat(190, 365, 610, 385);
CText txtDisplayCat(pOffScreenDC, pGamePalette, &rDisplayCat, JUSTIFY_CENTER);
BeginWaitCursor();
nWordsLeft = WORDSPERLIST;
nWordList = brand() % NUMBEROFLISTS;
nIterations2 = 0;
for (y = 0; y < WORDSPERLIST; y++) {
if (nIterations2 > 500) {
nWordList++;
nWordList %= NUMBEROFLISTS; // keep nWordList in range of 0 to 49
nIterations2 = 0;
}
if (y == 0) {
for (x = 0; x < NUMBEROFROWS; x++) {
for (z = 0; z < NUMBEROFCOLS; z++) {
acGameGrid[x][z] = '\0';
}
}
for (x = 0; x < WORDSPERLIST; x++) {
_strGameList[x].Empty();
_strGameListDisplay[x].Empty();
}
}
for (x = 0; x < 21; x++) {
cTemp1[x] = '\0';
cTemp2[x] = '\0';
}
for (x = 0, z = 0; x < 20; x++, z++) {
if (acList[nWordList][y][x] != cSpace) {
cTemp1[z] = acList[nWordList][y][x];
} else
z--;
cTemp2[x] = acList[nWordList][y][x];
}
_strGameList[y] = cTemp1;
_strGameListDisplay[y] = cTemp2;
nWordLen = strlen(cTemp1);
bTemp1 = true;
if (m_bWordsForwardOnly)
nDirection = brand() % 4;
else
nDirection = brand() % 8;
while (bTemp1) {
nIterations1++;
if (nIterations1 > 500) {
nIterations1 = 0;
nIterations2++;
y = -1;
bTemp1 = false;
continue;
}
ptSPos.x = brand() % NUMBEROFCOLS;
ptSPos.y = brand() % NUMBEROFROWS;
if (m_bWordsForwardOnly)
switch (nDirection) {
case 0:
nDirection = 0;
break;
case 1:
nDirection = 1;
break;
case 2:
nDirection = 2;
break;
case 3:
nDirection = 7;
break;
} else {
switch (nDirection) {
case 0:
nDirection = 2;
break;
case 1:
nDirection = 3;
break;
case 2:
nDirection = 4;
break;
case 3:
nDirection = 5;
break;
case 4:
nDirection = 6;
break;
case 5:
nDirection = 7;
break;
case 6:
nDirection = 0;
break;
case 7:
nDirection = 1;
break;
}
}
switch (nDirection) {
case 0: // going right
if (ptSPos.x + nWordLen >= NUMBEROFCOLS)
continue;
bTemp2 = true;
for (z = 0; z < nWordLen; z++) {
if ((acGameGrid[ptSPos.y][ptSPos.x + z] != '\0') &&
(acGameGrid[ptSPos.y][ptSPos.x + z] != cTemp1[z])) {
bTemp2 = false;
}
}
if (bTemp2 == false)
continue;
for (z = 0; z < nWordLen; z++) {
acGameGrid[ptSPos.y][ptSPos.x + z] = cTemp1[z];
bTemp1 = false;
}
break;
case 1: // going down and right
if (ptSPos.x + nWordLen >= NUMBEROFCOLS)
continue;
if (ptSPos.y + nWordLen >= NUMBEROFROWS)
continue;
bTemp2 = true;
for (z = 0; z < nWordLen; z++) {
if ((acGameGrid[ptSPos.y + z][ptSPos.x + z] != '\0') &&
(acGameGrid[ptSPos.y + z][ptSPos.x + z] != cTemp1[z])) {
bTemp2 = false;
}
}
if (bTemp2 == false)
continue;
for (z = 0; z < nWordLen; z++) {
acGameGrid[ptSPos.y + z][ptSPos.x + z] = cTemp1[z];
bTemp1 = false;
}
break;
case 2: // going down
if (ptSPos.y + nWordLen >= NUMBEROFROWS)
continue;
bTemp2 = true;
for (z = 0; z < nWordLen; z++) {
if ((acGameGrid[ptSPos.y + z][ptSPos.x] != '\0') &&
(acGameGrid[ptSPos.y + z][ptSPos.x] != cTemp1[z])) {
bTemp2 = false;
}
}
if (bTemp2 == false)
continue;
for (z = 0; z < nWordLen; z++) {
acGameGrid[ptSPos.y + z][ptSPos.x] = cTemp1[z];
bTemp1 = false;
}
break;
case 3: // going down and left
if (ptSPos.y + nWordLen >= NUMBEROFROWS)
continue;
if (ptSPos.x - nWordLen < 0)
continue;
bTemp2 = true;
for (z = 0; z < nWordLen; z++) {
if ((acGameGrid[ptSPos.y + z][ptSPos.x - z] != '\0') &&
(acGameGrid[ptSPos.y + z][ptSPos.x - z] != cTemp1[z])) {
bTemp2 = false;
}
}
if (bTemp2 == false)
continue;
for (z = 0; z < nWordLen; z++) {
acGameGrid[ptSPos.y + z][ptSPos.x - z] = cTemp1[z];
bTemp1 = false;
}
break;
case 4: // going left
if (ptSPos.x - nWordLen < 0)
continue;
bTemp2 = true;
for (z = 0; z < nWordLen; z++) {
if ((acGameGrid[ptSPos.y][ptSPos.x - z] != '\0') &&
(acGameGrid[ptSPos.y][ptSPos.x - z] != cTemp1[z])) {
bTemp2 = false;
}
}
if (bTemp2 == false)
continue;
for (z = 0; z < nWordLen; z++) {
acGameGrid[ptSPos.y][ptSPos.x - z] = cTemp1[z];
bTemp1 = false;
}
break;
case 5: // going up and left
if (ptSPos.x - nWordLen < 0)
continue;
if (ptSPos.y - nWordLen < 0)
continue;
bTemp2 = true;
for (z = 0; z < nWordLen; z++) {
if ((acGameGrid[ptSPos.y - z][ptSPos.x - z] != '\0') &&
(acGameGrid[ptSPos.y - z][ptSPos.x - z] != cTemp1[z])) {
bTemp2 = false;
}
}
if (bTemp2 == false)
continue;
for (z = 0; z < nWordLen; z++) {
acGameGrid[ptSPos.y - z][ptSPos.x - z] = cTemp1[z];
bTemp1 = false;
}
break;
case 6: // going up
if (ptSPos.y - nWordLen < 0)
continue;
bTemp2 = true;
for (z = 0; z < nWordLen; z++) {
if ((acGameGrid[ptSPos.y - z][ptSPos.x] != '\0') &&
(acGameGrid[ptSPos.y - z][ptSPos.x] != cTemp1[z])) {
bTemp2 = false;
}
}
if (bTemp2 == false)
continue;
for (z = 0; z < nWordLen; z++) {
acGameGrid[ptSPos.y - z][ptSPos.x] = cTemp1[z];
bTemp1 = false;
}
break;
case 7: // going up and right
if (ptSPos.x + nWordLen >= NUMBEROFCOLS)
continue;
if (ptSPos.y - nWordLen < 0)
continue;
bTemp2 = true;
for (z = 0; z < nWordLen; z++) {
if ((acGameGrid[ptSPos.y - z][ptSPos.x + z] != '\0') &&
(acGameGrid[ptSPos.y - z][ptSPos.x + z] != cTemp1[z])) {
bTemp2 = false;
}
}
if (bTemp2 == false)
continue;
for (z = 0; z < nWordLen; z++) {
acGameGrid[ptSPos.y - z][ptSPos.x + z] = cTemp1[z];
bTemp1 = false;
}
break;
}
}
}
for (y = 0; y < NUMBEROFROWS; y++) {
for (x = 0; x < NUMBEROFCOLS; x++) {
if (acGameGrid[y][x] == '\0')
acGameGrid[y][x] = acAlpha[(brand() % 26)];
}
}
PaintBitmap(pOffScreenDC, pGamePalette, pbmpSplashScreen, 0, 0, GAME_WIDTH, GAME_HEIGHT);
for (y = 0; y < NUMBEROFROWS; y++) {
for (x = 0; x < NUMBEROFCOLS; x++) {
int a, b;
CRect rTemp;
a = ((int)(acGameGrid[y][x]) - 65);
b = 0; // 21 if grey letter
rTemp.SetRect((a * 21), (b), ((a * 21) + 20), (b + 20));
BltMaskedBitmap(pOffScreenDC, pGamePalette, pbmpAllLetters,
&rTemp, arScreenGrid[y][x].left, arScreenGrid[y][x].top);
}
}
strTemp = "Category: ";
strTemp += astrWLCat[nWordList];
txtDisplayCat.DisplayString(pOffScreenDC, strTemp, 16, FW_BOLD, DK_CYAN); //Shadowed
char cDisplayTemp[32];
Common::sprintf_s(cDisplayTemp, "Words Left: %i", nWordsLeft);
ptxtScore->DisplayString(pOffScreenDC, cDisplayTemp, 16, FW_BOLD, DK_CYAN); //Shadowed
m_bNoGrid = false;
EndWaitCursor();
return;
}
/*****************************************************************
*
* OnCommand
*
* FUNCTIONAL DESCRIPTION:
*
* Process the QUIT and OKAY buttons when they are clicked.
*
* This function is called when a WM_COMMAND message is issued,
* typically in order to process control related activities.
*
* FORMAL PARAMETERS:
*
* wParam identifier for the button to be processed
* lParam type of message to be processed
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
// OnCommand
//
void CALLBACK lpfnOptionCallback(CWnd * pWnd) {
// do the mini options dialog
int nOption = 0; // return from the Options dialog
CWSOptDlg dlgMiniOptDlg(pWnd, pGamePalette, IDD_MINIOPTIONS_DIALOG);
dlgMiniOptDlg.SetInitialOptions(pMainGameWnd->m_nTimeForGame,
pMainGameWnd->m_bShowWordList,
pMainGameWnd->m_bWordsForwardOnly);
nOption = dlgMiniOptDlg.DoModal();
if (nOption > 0) {
if (nOption >= 20000) {
pMainGameWnd->m_bWordsForwardOnly = false;
nOption -= 20000;
} else {
pMainGameWnd->m_bWordsForwardOnly = true;
nOption -= 10000;
}
if (nOption >= 2000) {
pMainGameWnd->m_bShowWordList = false;
nOption -= 2000;
} else {
pMainGameWnd->m_bShowWordList = true;
nOption -= 1000;
}
pMainGameWnd->m_nTimeForGame = nOption;
bResetGame = true;
}
return;
}
bool CMainWSWindow::OnCommand(WPARAM wParam, LPARAM lParam) {
int nMainOption = 0; // return from the Options dialog
if (HIWORD(lParam) == BN_CLICKED) { // only want to look at button clicks
switch (wParam) {
// Option button clicked, then put up the Options dialog
case IDC_OPTION:
pOptionButton->EnableWindow(false);
bResetGame = false;
KillTimer(GAMETIMER);
if (m_lpGameStruct->bPlayingMetagame == true) {
CMainMenu dlgMainOpts((CWnd *)this, pGamePalette, (NO_NEWGAME | NO_OPTIONS),
lpfnOptionCallback, RULESFILE,
(m_lpGameStruct->bSoundEffectsEnabled ? RULES_WAV : nullptr),
m_lpGameStruct);
nMainOption = dlgMainOpts.DoModal();
switch (nMainOption) {
case IDC_OPTIONS_QUIT:
// if Quit buttons was hit, quit
PostMessage(WM_CLOSE, 0, 0);
break;
}
} else {
CMainMenu dlgMainOpts((CWnd *)this, pGamePalette, 0,
lpfnOptionCallback, RULESFILE,
(m_lpGameStruct->bSoundEffectsEnabled ? RULES_WAV : nullptr),
m_lpGameStruct);
nMainOption = dlgMainOpts.DoModal();
switch (nMainOption) {
case IDC_OPTIONS_QUIT:
// if Quit buttons was hit, quit
PostMessage(WM_CLOSE, 0, 0);
break;
case IDC_OPTIONS_NEWGAME:
// reset the game and start a new hand
bResetGame = true;
break;
}
}
pOptionButton->EnableWindow(true);
//
// Check to see if the music state was changed and adjust to match it
//
if ((m_lpGameStruct->bMusicEnabled == false) && (pGameSound != nullptr)) {
if (pGameSound->playing())
pGameSound->stop();
} else if (m_lpGameStruct->bMusicEnabled) {
if (pGameSound == nullptr) {
pGameSound = new CSound(this, GAME_THEME,
SOUND_MIDI | SOUND_LOOP | SOUND_DONT_LOOP_TO_END);
}
if (pGameSound != nullptr) {
if (!pGameSound->playing())
(*pGameSound).midiLoopPlaySegment(500, 31500, 0, FMT_MILLISEC);
}
}
if (bResetGame && !m_lpGameStruct->bPlayingMetagame)
ResetGame();
else if ((m_nTimeForGame > 0) && (m_bNoGrid == false)) {
long lTemp = (long)m_nTimeForGame * 1000;
nTimerRes = (unsigned int)(lTemp / (TIMERSPRITECELS - 1));
// nTimerRes = ( ( m_nTimeForGame * 1000 ) / TIMERSPRITECELS );
SetTimer(GAMETIMER, nTimerRes, nullptr);
}
break;
}
}
(*this).SetFocus(); // Reset focus back to the main window
return true;
}
void CMainWSWindow::OnLButtonDown(unsigned int nFlags, CPoint point) {
CDC *pDC = nullptr;
CPalette *pTempPal = nullptr;
CRect rChicken,
rPig,
rCow,
rFlower;
int x, y;
rChicken.SetRect(CHICKEN_X, CHICKEN_Y, CHICKEN_X + CHICKEN_DX, CHICKEN_Y + CHICKEN_DY);
rPig.SetRect(PIG_X, PIG_Y, PIG_X + PIG_DX, PIG_Y + PIG_DY);
rCow.SetRect(COW_X, COW_Y, COW_X + COW_DX, COW_Y + COW_DY);
rFlower.SetRect(FLOWER_X, FLOWER_Y, FLOWER_X + FLOWER_DX, FLOWER_Y + FLOWER_DY);
if (m_lpGameStruct->bPlayingMetagame == false) {
if (rNewGame.PtInRect(point)) {
SetCapture();
m_bMouseCaptured = true;
}
}
pDC = GetDC();
if (rChicken.PtInRect(point)) {
CSound::waitWaveSounds();
sndPlaySound(nullptr, 0);
PlayEasterEgg(pDC, (CWnd *)this, pGamePalette, CHICKEN_ANIM, CHICKEN_WAV, NUM_CHICKEN_CELS,
CHICKEN_X, CHICKEN_Y, CHICKEN_SLEEP, (*m_lpGameStruct).bSoundEffectsEnabled);
} else if (rCow.PtInRect(point)) {
CSound::waitWaveSounds();
sndPlaySound(nullptr, 0);
PlayEasterEgg(pDC, (CWnd *)this, pGamePalette, COW_ANIM, COW_WAV, NUM_COW_CELS,
COW_X, COW_Y, COW_SLEEP, (*m_lpGameStruct).bSoundEffectsEnabled);
} else if (rPig.PtInRect(point) && (*m_lpGameStruct).bSoundEffectsEnabled) {
CSound::waitWaveSounds();
sndPlaySound(nullptr, 0);
sndPlaySound(PIG_WAV, SND_ASYNC);
} else if (rFlower.PtInRect(point) && (*m_lpGameStruct).bSoundEffectsEnabled) {
CSound::waitWaveSounds();
sndPlaySound(nullptr, 0);
sndPlaySound(FLOWER_WAV, SND_ASYNC);
}
ReleaseDC(pDC);
if (m_bNoGrid)
return;
for (y = 0; y < NUMBEROFROWS; y++) {
for (x = 0; x < NUMBEROFCOLS; x++) {
if (arScreenGrid[y][x].PtInRect(point)) {
CBrush cBrush((COLORREF)RGB(0, 255, 255));
pDC = GetDC();
pTempPal = pDC->SelectPalette(pGamePalette, false);
SetCapture();
pDC->RealizePalette();
m_bMouseCaptured = true;
ptCurrPosInGrid.x = x;
ptCurrPosInGrid.y = y;
ptOrigPosInGrid.x = x;
ptOrigPosInGrid.y = y;
ptLastPosInGrid.x = x;
ptLastPosInGrid.y = y;
pDC->FrameRect(&arScreenGrid[y][x], &cBrush);
pDC->SelectPalette(pTempPal, false);
ReleaseDC(pDC);
}
}
}
CWnd::OnLButtonDown(nFlags, point);
}
void CMainWSWindow::OnMouseMove(unsigned int nFlags, CPoint point) {
CDC *pDC = nullptr;
CBrush cBrush((COLORREF)RGB(0, 255, 255));
CPalette *pTempPal = nullptr;
CRgn FrameRgn;
POINT aptFrame[6];
int x, y;
int nCurrentX, nCurrentY;
SetCursor(LoadCursor(nullptr, IDC_ARROW)); // Refresh cursor object
if (m_bNoGrid)
return;
if (m_bMouseCaptured) {
for (int i = 0; i < 6; ++i)
aptFrame[i].x = aptFrame[i].y = 0;
for (y = 0; y < NUMBEROFROWS; y++) {
for (x = 0; x < NUMBEROFCOLS; x++) {
if (arScreenGrid[y][x].PtInRect(point)) {
ptCurrPosInGrid.x = x;
ptCurrPosInGrid.y = y;
}
}
}
if ((ptCurrPosInGrid.x != ptLastPosInGrid.x) ||
(ptCurrPosInGrid.y != ptLastPosInGrid.y)) {
for (x = 0; x < WORDSPERLIST; x++)
acWordChosen[x] = '\0';
// draw vertical box
if (ptCurrPosInGrid.x == ptOrigPosInGrid.x) {
if (ptCurrPosInGrid.y >= ptOrigPosInGrid.y) {
// start from the top and go down
aptFrame[0].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[0].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[1].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[1].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[2].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[2].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[3].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[3].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[4].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[4].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
aptFrame[5].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[5].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
// put the selected word into acWordChosen
for (y = ptOrigPosInGrid.y; y <= ptCurrPosInGrid.y; y++) {
acWordChosen[ y - ptOrigPosInGrid.y ] = acGameGrid[y][ptOrigPosInGrid.x];
}
} else {
// start from the bottom and go up
aptFrame[0].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[0].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[1].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[1].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[2].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[2].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[3].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[3].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[4].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[4].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
aptFrame[5].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[5].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
// put the selected word into acWordChosen
for (y = ptCurrPosInGrid.y; y <= ptOrigPosInGrid.y; y++) {
acWordChosen[ y - ptCurrPosInGrid.y ] = acGameGrid[y][ptCurrPosInGrid.x];
}
}
}
// draw horizontal box
if (ptCurrPosInGrid.y == ptOrigPosInGrid.y) {
if (ptCurrPosInGrid.x >= ptOrigPosInGrid.x) {
// start from the left and go right
aptFrame[0].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[0].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[1].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[1].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[2].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[2].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[3].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[3].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[4].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[4].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
aptFrame[5].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[5].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
// put the selected word into acWordChosen
for (x = ptOrigPosInGrid.x; x <= ptCurrPosInGrid.x; x++) {
acWordChosen[ x - ptOrigPosInGrid.x ] = acGameGrid[ptOrigPosInGrid.y][x];
}
} else {
// start from the right and go left
aptFrame[0].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[0].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[1].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[1].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[2].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[2].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[3].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[3].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[4].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[4].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
aptFrame[5].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[5].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
// put the selected word into acWordChosen
for (x = ptCurrPosInGrid.x; x <= ptOrigPosInGrid.x; x++) {
acWordChosen[ x - ptCurrPosInGrid.x ] = acGameGrid[ptCurrPosInGrid.y][x];
}
}
}
nCurrentX = ptCurrPosInGrid.x - ptOrigPosInGrid.x;
nCurrentY = ptCurrPosInGrid.y - ptOrigPosInGrid.y;
if ((nCurrentX - nCurrentY) == 0) { // diagnol with slope -1
if (ptCurrPosInGrid.x > ptOrigPosInGrid.x) {
aptFrame[0].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[0].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[1].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[1].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[2].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[2].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[3].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[3].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
aptFrame[4].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[4].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
aptFrame[5].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[5].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
for (x = ptOrigPosInGrid.x, y = ptOrigPosInGrid.y; x <= ptCurrPosInGrid.x; x++, y++) {
acWordChosen[ x - ptOrigPosInGrid.x ] = acGameGrid[y][x];
}
} else {
aptFrame[0].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[0].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[1].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[1].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[2].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[2].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[3].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[3].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
aptFrame[4].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[4].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
aptFrame[5].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[5].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
for (x = ptCurrPosInGrid.x, y = ptCurrPosInGrid.y; x <= ptOrigPosInGrid.x; x++, y++) {
acWordChosen[ x - ptCurrPosInGrid.x ] = acGameGrid[y][x];
}
}
} else {
if ((nCurrentX + nCurrentY) == 0) { // diagnol with slope 1
if (ptCurrPosInGrid.x > ptOrigPosInGrid.x) {
aptFrame[0].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[0].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[1].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[1].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[2].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[2].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[3].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[3].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
aptFrame[4].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[4].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
aptFrame[5].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[5].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
for (x = ptOrigPosInGrid.x, y = ptOrigPosInGrid.y; x <= ptCurrPosInGrid.x; x++, y--) {
acWordChosen[ x - ptOrigPosInGrid.x ] = acGameGrid[y][x];
}
} else {
aptFrame[0].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[0].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].top;
aptFrame[1].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].left;
aptFrame[1].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[2].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[2].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].top;
aptFrame[3].x = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].right;
aptFrame[3].y = arScreenGrid[ptOrigPosInGrid.y][ptOrigPosInGrid.x].bottom;
aptFrame[4].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].right;
aptFrame[4].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
aptFrame[5].x = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].left;
aptFrame[5].y = arScreenGrid[ptCurrPosInGrid.y][ptCurrPosInGrid.x].bottom;
for (x = ptCurrPosInGrid.x, y = ptCurrPosInGrid.y; x <= ptOrigPosInGrid.x; x++, y--) {
acWordChosen[ x - ptCurrPosInGrid.x ] = acGameGrid[y][x];
}
}
}
}
// redraw only what's necessary
RedrawWindow(&rRefreshRect);
pDC = GetDC();
pTempPal = pDC->SelectPalette(pGamePalette, false);
pDC->RealizePalette();
FrameRgn.CreatePolygonRgn(aptFrame, 6, WINDING);
pDC->FrameRgn(&FrameRgn, &cBrush, 1, 1);
}
ptLastPosInGrid.x = ptCurrPosInGrid.x;
ptLastPosInGrid.y = ptCurrPosInGrid.y;
}
if (pDC != nullptr) {
pDC->SelectPalette(pTempPal, false);
ReleaseDC(pDC);
}
CWnd::OnMouseMove(nFlags, point);
}
void CMainWSWindow::OnLButtonUp(unsigned int nFlags, CPoint point) {
int x, y;
POINT ptTemp;
bool bFoundWord = false;
int nWordNum = 0;
int a, b;
CRect rTemp;
if (m_bMouseCaptured) {
m_bMouseCaptured = false;
ReleaseCapture();
if (rNewGame.PtInRect(point) && !m_lpGameStruct->bPlayingMetagame) {
ResetGame();
return;
}
if (m_bNoGrid)
return;
for (x = 0; x < WORDSPERLIST; x++)
acWordBack[x] = '\0';
if (acWordChosen[0] != '\0') {
for (x = 0, y = (strlen(acWordChosen) - 1); y >= 0 ; x++, y--)
acWordBack[x] = acWordChosen[y];
for (x = 0; x < WORDSPERLIST; x++) {
bFoundWord = false;
nWordNum = 0;
if (_strGameList[x].IsEmpty() == false) {
if (_strGameList[x] == acWordChosen) {
bFoundWord = true;
nWordNum = x;
break;
} else {
if (_strGameList[x] == acWordBack) {
bFoundWord = true;
nWordNum = x;
break;
}
}
}
}
if (bFoundWord) {
if ((*m_lpGameStruct).bSoundEffectsEnabled) {
sndPlaySound(nullptr, 0);
sndPlaySound(FIND_WAV, SND_ASYNC);
}
_strGameList[nWordNum].Empty();
nWordsLeft--;
char cDisplayTemp[32];
Common::sprintf_s(cDisplayTemp, "Words Left: %i", nWordsLeft);
ptxtScore->DisplayString(pOffScreenDC, cDisplayTemp, 16, FW_BOLD, DK_CYAN);
ptTemp.x = ptOrigPosInGrid.x;
ptTemp.y = ptOrigPosInGrid.y;
a = ((int)(acGameGrid[ptTemp.y][ptTemp.x]) - 65);
b = 22;
rTemp.SetRect((a * 21), (b), ((a * 21) + 20), (b + 20));
BltMaskedBitmap(pOffScreenDC, pGamePalette, pbmpAllLetters,
&rTemp,
arScreenGrid[ptTemp.y][ptTemp.x].left,
arScreenGrid[ptTemp.y][ptTemp.x].top);
do {
if ((ptCurrPosInGrid.y == ptOrigPosInGrid.y) && (ptCurrPosInGrid.x > ptOrigPosInGrid.x)) {
// word direction right
ptTemp.x++;
} else {
if ((ptCurrPosInGrid.y > ptOrigPosInGrid.y) && (ptCurrPosInGrid.x > ptOrigPosInGrid.x)) {
// word direction down and right
ptTemp.x++;
ptTemp.y++;
} else {
if ((ptCurrPosInGrid.y > ptOrigPosInGrid.y) && (ptCurrPosInGrid.x == ptOrigPosInGrid.x)) {
// word direction down
ptTemp.y++;
} else {
if ((ptCurrPosInGrid.y > ptOrigPosInGrid.y) && (ptCurrPosInGrid.x < ptOrigPosInGrid.x)) {
// word direction down and left
ptTemp.x--;
ptTemp.y++;
} else {
if ((ptCurrPosInGrid.y == ptOrigPosInGrid.y) && (ptCurrPosInGrid.x < ptOrigPosInGrid.x)) {
// word direction left
ptTemp.x--;
} else {
if ((ptCurrPosInGrid.y < ptOrigPosInGrid.y) && (ptCurrPosInGrid.x < ptOrigPosInGrid.x)) {
// word direction up and left
ptTemp.x--;
ptTemp.y--;
} else {
if ((ptCurrPosInGrid.y < ptOrigPosInGrid.y) && (ptCurrPosInGrid.x == ptOrigPosInGrid.x)) {
// word direction up
ptTemp.y--;
} else {
if ((ptCurrPosInGrid.y < ptOrigPosInGrid.y) && (ptCurrPosInGrid.x > ptOrigPosInGrid.x)) {
// word direction up and right
ptTemp.x++;
ptTemp.y--;
}
}
}
}
}
}
}
}
a = ((int)(acGameGrid[ptTemp.y][ptTemp.x]) - 65);
b = 22;
rTemp.SetRect((a * 21), (b), ((a * 21) + 20), (b + 20));
BltMaskedBitmap(pOffScreenDC, pGamePalette, pbmpAllLetters,
&rTemp,
arScreenGrid[ptTemp.y][ptTemp.x].left,
arScreenGrid[ptTemp.y][ptTemp.x].top);
} while ((ptTemp.x != ptCurrPosInGrid.x) || (ptTemp.y != ptCurrPosInGrid.y));
} // end if bWordFound
else {
if ((*m_lpGameStruct).bSoundEffectsEnabled) {
sndPlaySound(nullptr, 0);
sndPlaySound(NOPE_WAV, SND_SYNC);
sndPlaySound(TRYAGAIN_WAV, SND_SYNC);
}
} // end else
}
RedrawWindow(&rRefreshRect);
if (nWordsLeft == 0) {
CMsgDlg msgGameOver((CWnd *)this, pGamePalette);
KillTimer(GAMETIMER);
m_bNoGrid = true;
if ((*m_lpGameStruct).bSoundEffectsEnabled) {
sndPlaySound(nullptr, 0);
sndPlaySound(ALLFOUND_WAV, SND_SYNC); // play sound
}
msgGameOver.SetInitialOptions(1, nWordsLeft);
msgGameOver.DoModal();
if (m_lpGameStruct->bPlayingMetagame)
PostMessage(WM_CLOSE, 0, 0);
}
}
CWnd::OnLButtonUp(nFlags, point);
}
void CMainWSWindow::OnRButtonDown(unsigned int nFlags, CPoint point) {
if (m_bShowWordList) {
CLongDialog dlgWordlist((CWnd *)this, pGamePalette, "OK", "Word", "list");
dlgWordlist.DoModal();
}
}
void CMainWSWindow::OnSysKeyDown(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {
// terminate app on ALT_F4
//
if ((nChar == VK_F4) && (nFlags & 0x2000)) {
PostMessage(WM_CLOSE, 0, 0);
} else {
// default action
CWnd::OnSysKeyDown(nChar, nRepCnt, nFlags);
}
}
void CMainWSWindow::OnKeyDown(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {
CRules dlgRules((CWnd *)this, RULESFILE, pGamePalette, nullptr);
switch (nChar) {
case VK_F1:
pOptionButton->ShowWindow(SW_HIDE);
// UpdateWindow();
CSound::waitWaveSounds();
dlgRules.DoModal(); // invoke the help dialog box
pOptionButton->ShowWindow(SW_SHOWNORMAL);
break;
case VK_F2:
SendMessage(WM_COMMAND, IDC_OPTION, BN_CLICKED);
break;
default:
CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags);
break;
}
return;
}
void CMainWSWindow::OnTimer(uintptr nWhichTimer) {
if (nWhichTimer == GAMETIMER) {
if (lCurrentTimer == (TIMERSPRITECELS - 1)) { //> ( TIMERSPRITECELS - 1 ) ) {
CDC *pDC = GetDC();
CMsgDlg msgGameOver((CWnd *)this, pGamePalette);
KillTimer(GAMETIMER);
nLastCell++;
pTimerSprite->SetCel(nLastCell);
pTimerSprite->PaintSprite(pDC, FLOWER_X, FLOWER_Y);
pTimerSprite->SetCel(nLastCell);
pTimerSprite->PaintSprite(pOffScreenDC, FLOWER_X, FLOWER_Y);
ReleaseDC(pDC);
m_bNoGrid = true;
if ((*m_lpGameStruct).bSoundEffectsEnabled) {
sndPlaySound(nullptr, 0);
sndPlaySound(TIMEOUT_WAV, SND_SYNC); // play sound
}
msgGameOver.SetInitialOptions(2, nWordsLeft);
msgGameOver.DoModal();
if (m_lpGameStruct->bPlayingMetagame)
PostMessage(WM_CLOSE, 0, 0);
else
RedrawWindow();
} else {
CDC *pDC = GetDC();
lCurrentTimer++;
nLastCell++;
if ((*m_lpGameStruct).bSoundEffectsEnabled) {
sndPlaySound(nullptr, 0);
sndPlaySound(TICK_WAV, SND_ASYNC);
}
pTimerSprite->SetCel(nLastCell);
pTimerSprite->PaintSprite(pDC, FLOWER_X, FLOWER_Y);
pTimerSprite->SetCel(nLastCell);
pTimerSprite->PaintSprite(pOffScreenDC, FLOWER_X, FLOWER_Y);
ReleaseDC(pDC);
}
}
return;
}
/*****************************************************************
*
* OnXXXXXX
*
* FUNCTIONAL DESCRIPTION:
*
* These functions are called when ever the corresponding WM_
* event message is generated for the mouse.
*
* (Add game-specific processing)
*
* FORMAL PARAMETERS:
*
* [Show arguments]
*
* IMPLICIT INPUT PARAMETERS:
*
* [External data read]
*
* IMPLICIT OUTPUT PARAMETERS:
*
* [External data modified]
*
* RETURN VALUE:
*
* [Discuss return value]
*
****************************************************************/
bool CMainWSWindow::OnEraseBkgnd(CDC *pDC) {
// eat this
return true;
}
void CMainWSWindow::OnActivate(unsigned int nState, CWnd *pWndOther, bool bMinimized) {
if (!bMinimized)
switch (nState) {
case WA_ACTIVE:
case WA_CLICKACTIVE:
InvalidateRect(nullptr, false);
break;
}
return;
}
/*****************************************************************
*
* OnClose
*
* FUNCTIONAL DESCRIPTION:
*
* This function is called when a Close event is generated. For
* this sample application we need only kill our event timer;
* The ExitInstance will handle releasing resources.
*
* FORMAL PARAMETERS:
*
* n/a
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
void CMainWSWindow::OnClose() {
CDC *pDC = GetDC();
CRect rctFillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
CBrush Brush(RGB(0, 0, 0));
pDC->FillRect(&rctFillRect, &Brush);
ReleaseDC(pDC);
ReleaseResources();
CFrameWnd ::OnClose();
}
/*****************************************************************
*
* OnDestroy
*
* FUNCTIONAL DESCRIPTION:
*
* This function is called when after the window has been destroyed.
* For poker, we post a message bak to the calling app to tell it
* that the user has quit the game, and therefore the app can unload
* this DLLL
*
* FORMAL PARAMETERS:
*
* n/a
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
void CMainWSWindow::OnDestroy() {
// send a message to the calling app to tell it the user has quit the game
m_lpGameStruct->lScore = (WORDSPERLIST - nWordsLeft);
MFC::PostMessage(m_hCallAppWnd, WM_PARENTNOTIFY, WM_DESTROY, (LPARAM)m_lpGameStruct);
m_lpGameStruct = nullptr;
CFrameWnd::OnDestroy();
}
/*****************************************************************
*
* ReleaseResources
*
* FUNCTIONAL DESCRIPTION:
*
* Release all resources that were created and retained during the
* course of the game. This includes sprites in the sprite chain,
* the game color palette, and button controls.
*
* FORMAL PARAMETERS:
*
* n/a
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
void CMainWSWindow::ReleaseResources() {
if (pGameSound != nullptr) {
delete pGameSound; // delete the game theme song
pGameSound = nullptr;
}
CSound::clearSounds();
if (pTimerSprite != nullptr)
delete pTimerSprite;
if (pOldOffScreenBmp != nullptr)
pOffScreenDC->SelectObject(pOldOffScreenBmp);
if (pOldOffScreenPal != nullptr)
pOffScreenDC->SelectPalette(pOldOffScreenPal, false);
if (pOffScreenDC->m_hDC != nullptr) {
pOffScreenDC->DeleteDC();
delete pOffScreenDC;
}
if (pOffScreenBmp != nullptr) {
pOffScreenBmp->DeleteObject();
delete pOffScreenBmp;
}
if (pbmpSplashScreen != nullptr) {
pbmpSplashScreen->DeleteObject();
delete pbmpSplashScreen;
}
if (pbmpAllLetters != nullptr) {
pbmpAllLetters->DeleteObject();
delete pbmpAllLetters;
}
if (ptxtScore != nullptr)
delete ptxtScore;
if (pGamePalette != nullptr) {
pGamePalette->DeleteObject(); // release the game color palette
delete pGamePalette;
}
delete pOptionButton; // release the buttons we used
return;
}
/*****************************************************************
*
* FlushInputEvents
*
* FUNCTIONAL DESCRIPTION:
*
* Remove all keyboard and mouse related events from the message
* so that they will not be sent to us for processing; i.e. this
* flushes keyboard type ahead and extra mouse clicks and movement.
*
* FORMAL PARAMETERS:
*
* n/a
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
void CMainWSWindow::FlushInputEvents() {
MSG msg;
while (true) { // find and remove all keyboard events
if (!PeekMessage(&msg, nullptr, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
break;
}
while (true) { // find and remove all mouse events
if (!PeekMessage(&msg, nullptr, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE))
break;
}
}
//////////// Additional Sound Notify routines //////////////
LRESULT CMainWSWindow::OnMCINotify(WPARAM wParam, LPARAM lParam) {
CSound *pSound;
pSound = CSound::OnMCIStopped(wParam, lParam);
if (pSound != nullptr)
OnSoundNotify(pSound);
return 0;
}
LRESULT CMainWSWindow::OnMMIONotify(WPARAM wParam, LPARAM lParam) {
CSound *pSound;
pSound = CSound::OnMMIOStopped(wParam, lParam);
if (pSound != nullptr)
OnSoundNotify(pSound);
return 0;
}
void CMainWSWindow::OnSoundNotify(CSound *pSound) {
//
// Add your code to process explicit notification of a sound "done" event here.
// pSound is a pointer to a CSound object for which you requested SOUND_NOTIFY.
//
}
// CMainWSWindow message map:
// Associate messages with member functions.
//
BEGIN_MESSAGE_MAP(CMainWSWindow, CFrameWnd)
//{{AFX_MSG_MAP( CMainWSWindow )
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_CLOSE()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_ERASEBKGND()
ON_WM_KEYDOWN()
ON_WM_SYSKEYDOWN()
ON_WM_ACTIVATE()
ON_MESSAGE(MM_MCINOTIFY, CMainWSWindow::OnMCINotify)
ON_MESSAGE(MM_WOM_DONE, CMainWSWindow::OnMMIONotify)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void PlayEasterEgg(CDC *pDC, CWnd *pWnd, CPalette *pPalette,
const char *pszAnimFile, const char *pszSoundFile,
int nNumCels, int nXLoc, int nYLoc, int nSleep, bool bPlaySound) {
CSprite *pSprite = nullptr;
CSound *pEffect = nullptr;
bool bSuccess;
int i;
pSprite = new CSprite;
(*pSprite).SharePalette(pPalette);
bSuccess = (*pSprite).LoadCels(pDC, pszAnimFile, nNumCels);
if (!bSuccess) {
delete pSprite;
return;
}
(*pSprite).SetMasked(false);
(*pSprite).SetMobile(false);
if (bPlaySound) {
pEffect = new CSound(pWnd, pszSoundFile, // Load up the sound file as a
SOUND_WAVE | SOUND_ASYNCH | SOUND_QUEUE | SOUND_AUTODELETE); //...Wave file, to delete itself
}
if (pEffect != nullptr) {
bSuccess = (*pEffect).play();
if (!bSuccess)
delete pEffect;
}
(*pSprite).SetCel(-1); // nNumCels
for (i = 0; i < nNumCels; i++) {
(*pSprite).PaintSprite(pDC, nXLoc, nYLoc);
Sleep(nSleep);
}
if (pSprite != nullptr)
delete pSprite;
} // end PlayEasterEgg
} // namespace WordSearch
} // namespace HodjNPodj
} // namespace Bagel