//====================================================================== //Battleship - Version 1.2 //Copyright (C) 2004 Jake Poznanski (jake@ti-news.net) // //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 2 //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, write to the Free Software //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //====================================================================== #include // For all that Windows stuff #include // Command bar includes #include // Pocket PC includes #include #include #include "Main.h" // Program-specific stuff #include "ExPPCIncs.h" // Adds back PPC SDK stuff #include "resource.h" //---------------------------------------------------------------------- // Global data const TCHAR szAppName[] = TEXT("Battleship"); const TCHAR szWindowName[] = TEXT("Battleship"); HINSTANCE hInst; // Program instance handle HWND hwndMenuBar = NULL; // Handle of menu bar control SHACTIVATEINFO sai; // Used to adjust window for SIP // Message dispatch table for MainWindowProc const struct decodeUINT MainMessages[] = { WM_CREATE, DoCreateMain, WM_SIZE, DoSizeMain, WM_COMMAND, DoCommandMain, WM_NOTIFY, DoNotifyMain, WM_SETTINGCHANGE, DoSettingChangeMain, WM_ACTIVATE, DoActivateMain, WM_DESTROY, DoDestroyMain, WM_PAINT, DoPaintMain, WM_LBUTTONUP, DoLButtonUpMain, }; // Command Message dispatch for MainWindowProc const struct decodeCMD MainCommandItems[] = { IDM_EXIT, DoMainCommandExit, IDM_ABOUT, DoMainCommandAbout, IDM_NEWGAME, DoMainCommandNewGame, IDM_HELP, DoMainCommandHelp, IDM_OPTIONS, DoMainCommandOptions, }; //====================================================================== // Program entry point // int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { MSG msg; int rc = 0; HWND hwndMain; HACCEL hAccel; // Initialize application. hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow); if (hwndMain == 0) return 0x10; hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE (ID_ACCEL)); // Application message loop while (GetMessage (&msg, NULL, 0, 0)) { // Translate accelerator keys. if (!TranslateAccelerator(hwndMain, hAccel, &msg)) { TranslateMessage (&msg); DispatchMessage (&msg); } } // Instance cleanup return TermInstance (hInstance, msg.wParam); } //------------------------------------------------------------------ // InitInstance - Instance initialization // HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow) { HWND hWnd; WNDCLASS wc; // Allow only one instance of the application. hWnd = FindWindow (szAppName, NULL); if (hWnd) { SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01)); return 0; } // Register application main window class. wc.style = CS_VREDRAW | CS_HREDRAW; // Window style wc.lpfnWndProc = MainWndProc; // Callback function wc.cbClsExtra = 0; // Extra class data wc.cbWndExtra = 0; // Extra window data wc.hInstance = hInstance; // Owner handle wc.hIcon = NULL, // Application icon wc.hCursor = LoadCursor (NULL, IDC_ARROW); // Default cursor wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wc.lpszMenuName = NULL; // Menu name wc.lpszClassName = szAppName; // Window class name if (RegisterClass (&wc) == 0) return 0; // Save program instance handle in global variable. hInst = hInstance; // Create main window. hWnd = CreateWindow (szAppName, szWindowName, WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (!IsWindow (hWnd)) return 0; // Fail if not created. // Standard show and update calls ShowWindow (hWnd, nCmdShow); UpdateWindow (hWnd); return hWnd; } //---------------------------------------------------------------------- // TermInstance - Program cleanup // int TermInstance (HINSTANCE hInstance, int nDefRC) { return nDefRC; } //====================================================================== // Message handling procedures for main window // //---------------------------------------------------------------------- // MainWndProc - Callback function for application window // LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { INT i; // // Search message list to see if we need to handle this // message. If in list, call procedure. // for (i = 0; i < dim(MainMessages); i++) { if (wMsg == MainMessages[i].Code) return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam); } return DefWindowProc (hWnd, wMsg, wParam, lParam); } //---------------------------------------------------------------------- // DoCreateMain - Process WM_CREATE message for window. // LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { SIPINFO si; int cx, cy; TCHAR* regKey = _T("Software\\Battleship"); TCHAR* optionKey = _T("OptSound"); HKEY key; DWORD dataType = REG_BINARY; int retVal = 0; DWORD disposition; BYTE optionValue = 0; DWORD dataSize; dataSize = sizeof(int); // Initialize the shell to activate info structure. memset (&sai, 0, sizeof (sai)); sai.cbSize = sizeof (sai); // Create menu bar and check for errors. //hwndMenuBar = MyCreateMenuBar (hWnd, ID_TOOLBAR1); hwndMenuBar = MyCreateMenuBar (hWnd, IDR_MENUBAR1); if (!hwndMenuBar) { MessageBox (hWnd, TEXT("Couldn\'t create MenuBar"), szAppName, MB_OK); DestroyWindow (hWnd); return 0; } // Query the sip state and size our window appropriately. memset (&si, 0, sizeof (si)); si.cbSize = sizeof (si); SHSipInfo(SPI_GETSIPINFO, 0, (PVOID)&si, FALSE); cx = si.rcVisibleDesktop.right - si.rcVisibleDesktop.left; cy = si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top; // If the sip is not shown, or is showing but not docked, the // desktop rect doesn't include the height of the menu bar. if (!(si.fdwFlags & SIPF_ON) || ((si.fdwFlags & SIPF_ON) && !(si.fdwFlags & SIPF_DOCKED))) { RECT rectMB; GetWindowRect (hwndMenuBar, &rectMB); cy -= (rectMB.bottom - rectMB.top); } InitBoard(); srand( (unsigned)GetTickCount() ); //See if registry key exists, if it does, load it's value into our program, if not, create it and set to default, then load into program LONG lResult = RegCreateKeyEx(HKEY_CURRENT_USER, regKey, 0, TEXT( "Test" ), 0, KEY_ALL_ACCESS, NULL, &key, &disposition); if (lResult == ERROR_SUCCESS) { if( disposition == REG_CREATED_NEW_KEY ) RegSetValueEx(key, optionKey, 0, REG_BINARY, (BYTE *) &optionValue, sizeof(optionValue)); else{ RegQueryValueEx(key, optionKey, 0, &dataType, (BYTE *) &retVal, &dataSize); if( retVal == 1 ) SoundEnabled = true; else SoundEnabled = false; } RegCloseKey(key); } SetWindowPos (hWnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER); return 0; } //---------------------------------------------------------------------- // DoSizeMain - Process WM_SIZE message for window. // LRESULT DoSizeMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam){ RECT rect; GetClientRect (hWnd, &rect); return 0; } //---------------------------------------------------------------------- // DoCommandMain - Process WM_COMMAND message for window. // LRESULT DoCommandMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { WORD idItem, wNotifyCode; HWND hwndCtl; INT i; // Parse the parameters. idItem = (WORD) LOWORD (wParam); wNotifyCode = (WORD) HIWORD (wParam); hwndCtl = (HWND) lParam; // Call routine to handle control message. for (i = 0; i < dim(MainCommandItems); i++) { if (idItem == MainCommandItems[i].Code) return (*MainCommandItems[i].Fxn)(hWnd, idItem, hwndCtl, wNotifyCode); } return 0; } //---------------------------------------------------------------------- // DoNotifyMain - Process WM_NOTIFY message for window. // LRESULT DoNotifyMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { return 0; } //---------------------------------------------------------------------- // DoSettingChangeMain - Process WM_SETTINGCHANGE message for window. // LRESULT DoSettingChangeMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { // Notify shell of our WM_SETTINGCHANGE message. SHHandleWMSettingChange(hWnd, wParam, lParam, &sai); return 0; } //---------------------------------------------------------------------- // DoActivateMain - Process WM_ACTIVATE message for window. // LRESULT DoActivateMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { // Notify shell of our activate message. SHHandleWMActivate(hWnd, wParam, lParam, &sai, 0); return 0; } //---------------------------------------------------------------------- // DoDestroyMain - Process WM_DESTROY message for window. // LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { //Should add code to set registry key TCHAR* regKey = _T("Software\\Battleship"); TCHAR* optionKey = _T("OptSound"); HKEY key; BYTE optionValue; DWORD dataType = REG_BINARY; int retVal = 0; DWORD disposition; if( SoundEnabled == true ) optionValue = 1; else optionValue = 0; LONG lResult = RegCreateKeyEx(HKEY_CURRENT_USER, regKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, &disposition); if (lResult == ERROR_SUCCESS) { RegSetValueEx(key, optionKey, 0, REG_BINARY, (BYTE *) &optionValue, sizeof(optionValue)); RegCloseKey(key); } PostQuitMessage (0); return 0; } //---------------------------------------------------------------------- // DoPaintMain - Process WM_PAINT message for window // LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam){ PAINTSTRUCT ps; RECT rect, rectText; HDC hdc, hdcWater, hdcMiss, hdcHit, hdcSunk; HBITMAP bmpWater, bmpMiss, bmpHit, bmpSunk; HBRUSH myBrush; HPEN myPen; TCHAR szOut[256]; int row, col; // Get the size of the client rectangle GetClientRect (hWnd, &rect); hdc = BeginPaint (hWnd, &ps); //Do painting stuff hdcWater= CreateCompatibleDC( hdc ); hdcMiss= CreateCompatibleDC( hdc ); hdcHit= CreateCompatibleDC( hdc ); hdcSunk= CreateCompatibleDC( hdc ); bmpWater = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP4)); bmpMiss = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1)); bmpHit = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP3)); bmpSunk = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP2)); SelectObject( hdcWater, bmpWater ); SelectObject( hdcMiss, bmpMiss ); SelectObject( hdcHit, bmpHit ); SelectObject( hdcSunk, bmpSunk ); for( row = 0; row < 8; row++ ) for( col = 0; col < 8; col++ ){ if( Board[ row][col] == 0 ) BitBlt( hdc, row * 30, col * 30, 30, 30, hdcWater, 0, 0, SRCCOPY ); else if( Board[ row][col] == 1 ) BitBlt( hdc, row * 30, col * 30, 30, 30, hdcMiss, 0, 0, SRCCOPY ); else if( Board[ row][col] >= 10 && Board[ row][col] <= 13 ) BitBlt( hdc, row * 30, col * 30, 30, 30, hdcWater, 0, 0, SRCCOPY ); else if( Board[ row][col] >= 20 && Board[ row][col] <= 23 ) BitBlt( hdc, row * 30, col * 30, 30, 30, hdcHit, 0, 0, SRCCOPY ); else if( Board[ row][col] >= 30 && Board[ row][col] <= 33 ) BitBlt( hdc, row * 30, col * 30, 30, 30, hdcSunk, 0, 0, SRCCOPY ); } if( GameStatus == GAME_PROGRESS ) wsprintf( szOut, TEXT( "Misses Left: %d" ), MissesLeft ); else if( GameStatus == GAME_LOST ) wsprintf( szOut, TEXT( "Game Over!!!" )); else if( GameStatus = GAME_WIN ){ if( MissesLeft == 1 ) wsprintf( szOut, TEXT( "You won with 1 miss left" ) ); else wsprintf( szOut, TEXT( "You won with %d misses left" ), MissesLeft ); } rectText.top = 245; rectText.bottom = 265; rectText.left = 0; rectText.right = rect.right; myPen = (HPEN)GetStockObject( WHITE_PEN ); myBrush = (HBRUSH)GetStockObject( WHITE_BRUSH ); SelectObject( hdc, myPen ); SelectObject( hdc, myBrush ); Rectangle( hdc, 0, 245, 240, 265 ); DrawText( hdc, szOut, -1, &rectText, DT_CENTER ); EndPaint( hWnd, &ps ); return 0; } //LButtonUp main handler LRESULT DoLButtonUpMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam){ int x, y, row, col, shipID, i; POINT pt; pt.x = LOWORD( lParam ); pt.y = HIWORD( lParam ); x = pt.x / 30; y = pt.y / 30; if( x < 8 && y < 8 && GameStatus == GAME_PROGRESS ){ if( Board[x][y] == 0 ){ //Miss if( SoundEnabled == true ) PlaySound (MAKEINTRESOURCE( IDR_WAVE3 ), hInst, SND_RESOURCE | SND_ASYNC); Board[x][y] = 1; MissesLeft--; if( MissesLeft <= 0 ){ if( SoundEnabled == true ) PlaySound (MAKEINTRESOURCE( IDR_WAVE5 ), hInst, SND_RESOURCE | SND_ASYNC); GameStatus = GAME_LOST; } } if( Board[x][y] >= 10 && Board[x][y] <= 13 ){ //You just hit a ship shipID = Board[x][y] - 10; //Update ship info array Ships[ shipID ][1]++; if( Ships[ shipID ][1] != Ships[ shipID ][0] ){ if( SoundEnabled == true ) PlaySound (MAKEINTRESOURCE( IDR_WAVE2 ), hInst, SND_RESOURCE | SND_ASYNC); //Normal Board[x][y] += 10; } else{ //Sunk if( SoundEnabled == true ) PlaySound (MAKEINTRESOURCE( IDR_WAVE1 ), hInst, SND_RESOURCE | SND_ASYNC); Board[x][y] += 10; //Fill in the thing for( row = 0; row < 10; row++ ) for( col = 0; col < 10; col++ ) if( Board[row][col] - 20 == shipID ) Board[row][col] += 10; } } //Check for wins bool winFlag = true; for( i = 0; i < ShipCount; i++ ) if( Ships[i][0] != Ships[i][1] ) winFlag = false; if( winFlag == true ){ GameStatus = GAME_WIN; if( SoundEnabled == true ) PlaySound (MAKEINTRESOURCE( IDR_WAVE4 ), hInst, SND_RESOURCE | SND_ASYNC); } } InvalidateRect( hWnd, NULL, FALSE ); return 0; } //====================================================================== // Command handler routines //---------------------------------------------------------------------- // DoMainCommandExit - Process Program Exit command. // LPARAM DoMainCommandExit (HWND hWnd, WORD idItem, HWND hwndCtl, WORD wNotifyCode) { SendMessage (hWnd, WM_CLOSE, 0, 0); return 0; } //---------------------------------------------------------------------- // DoMainCommandAbout - Process Help About command. // LPARAM DoMainCommandAbout (HWND hWnd, WORD idItem, HWND hwndCtl, WORD wNotifyCode) { DialogBox( hInst, MAKEINTRESOURCE( IDD_DIALOGABOUT ), hWnd, AboutDlgProc ); return 0; } //---------------------------------------------------------------------- // DoMainCommandAbout - Process Help OPtions command. // LPARAM DoMainCommandOptions (HWND hWnd, WORD idItem, HWND hwndCtl, WORD wNotifyCode) { DialogBox( hInst, MAKEINTRESOURCE( IDD_DIALOGOPT), hWnd, OptionsDlgProc ); return 0; } //---------------------------------------------------------------------- // DoMainCommandAbout - Process New Game command. // LPARAM DoMainCommandNewGame(HWND hWnd, WORD idItem, HWND hwndCtl, WORD wNotifyCode) { int x; GameStatus = GAME_PROGRESS; MissesLeft = MAXMISS; for( x=0; x