From 0c65afdb458fcb63936fd3db8a2b83ea89a9ef10 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Dec 2003 01:34:40 +0000 Subject: [PATCH] Partially applied patch #8618848 ("adjustment of bombs demo to wxBombsCE"). Applied the source changes only, not the project changes; (wx-)modernized the demo. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24919 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- demos/bombs/bombs.cpp | 376 +++++++++++++++++--------------- demos/bombs/bombs.h | 161 +++++++------- demos/bombs/bombs1.cpp | 478 ++++++++++++++++++++++++++--------------- demos/bombs/game.cpp | 150 +++++++------ demos/bombs/game.h | 125 ++++++++--- 5 files changed, 764 insertions(+), 526 deletions(-) diff --git a/demos/bombs/bombs.cpp b/demos/bombs/bombs.cpp index 1094797a7e..846f692072 100644 --- a/demos/bombs/bombs.cpp +++ b/demos/bombs/bombs.cpp @@ -2,7 +2,7 @@ // Name: bombs.cpp // Purpose: Bombs game // Author: P. Foggia 1996 -// Modified by: +// Modified by: Wlodzimierz Skiba (ABX) 2003 // Created: 1996 // RCS-ID: $Id$ // Copyright: (c) 1996 P. Foggia @@ -10,243 +10,275 @@ /////////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ -#pragma implementation +# pragma implementation #endif #include "wx/wxprec.h" +#ifdef __BORLANDC__ +# pragma hdrstop +#endif + #ifndef WX_PRECOMP - #include "wx/wx.h" +# include "wx/wx.h" #endif //precompiled headers #include "bombs.h" -#include #include -#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) -#include "bombs.xpm" +#ifndef __WXWINCE__ +# include +#endif + +#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) \ + || defined(__WXMAC__) || defined(__WXMGL__) +# include "bombs.xpm" #endif -IMPLEMENT_APP(AppClass) +IMPLEMENT_APP(BombsApp) + +#ifdef __WXWINCE__ + STDAPI_(__int64) CeGetRandomSeed(); +#endif // Called to initialize the program -bool AppClass::OnInit() +bool BombsApp::OnInit() { - srand((unsigned)time(NULL)); - - // Initialize all the top-level window members to NULL. - BombsFrame = NULL; - level=IDM_EASY; +#ifdef __WXWINCE__ + srand((unsigned) CeGetRandomSeed()); +#else + srand((unsigned) time(NULL)); +#endif - BombsFrame = - new BombsFrameClass(NULL, _T("wxBombs"), wxPoint(155, 165), wxSize(300, 300), wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX ); + m_frame = new BombsFrame(&m_game); - int xmax=BombsFrame->BombsCanvas->field_width*BombsFrame->BombsCanvas->x_cell*X_UNIT; - int ymax=BombsFrame->BombsCanvas->field_height*BombsFrame->BombsCanvas->y_cell*Y_UNIT; - BombsFrame->SetClientSize(xmax, ymax); + m_frame->NewGame(bombsID_EASY); - return TRUE; + return true; } -BEGIN_EVENT_TABLE(BombsFrameClass, wxFrame) - EVT_MENU(IDM_EASY, BombsFrameClass::OnEasy) - EVT_MENU(IDM_MEDIUM, BombsFrameClass::OnMedium) - EVT_MENU(IDM_DIFFICULT, BombsFrameClass::OnDifficult) - EVT_MENU(IDM_EXIT, BombsFrameClass::OnExit) - EVT_MENU(IDM_ABOUT, BombsFrameClass::OnAbout) - EVT_MENU(IDM_RESTART, BombsFrameClass::OnRestart) - EVT_CLOSE(BombsFrameClass::OnCloseWindow) +BEGIN_EVENT_TABLE(BombsFrame, wxFrame) + EVT_MENU(bombsID_EASY, BombsFrame::OnNewEasyGame) + EVT_MENU(bombsID_MEDIUM, BombsFrame::OnNewMediumGame) + EVT_MENU(bombsID_HARD, BombsFrame::OnNewHardGame) + EVT_MENU(wxID_EXIT, BombsFrame::OnExit) + EVT_MENU(wxID_ABOUT, BombsFrame::OnAbout) END_EVENT_TABLE() -BombsFrameClass::BombsFrameClass(wxFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, long style): - wxFrame(parent, -1, title, pos, size, style) +BombsFrame::BombsFrame(BombsGame *game) + : wxFrame(NULL, wxID_ANY, wxT("wxBombs"), wxDefaultPosition, + wxSize(300, 300), wxDEFAULT_DIALOG_STYLE|wxMINIMIZE_BOX) { - // Initialize child subwindow members. - BombsCanvas = NULL; - - SetIcon(wxICON(bombs)); - - CreateStatusBar(); - - // Create a menu bar for the frame - wxMenuBar *menuBar1 = new wxMenuBar; - wxMenu *menu1 = new wxMenu; - menu1->Append(IDM_EXIT, _T("E&xit")); // , "Quit the program"); - menu1->AppendSeparator(); - menu1->Append(IDM_ABOUT, _T("&About...")); // , "Infos on wxBombs"); - menuBar1->Append(menu1, _T("&File")); - wxMenu *menu2 = new wxMenu; - menu2->Append(IDM_RESTART, _T("&Restart")); // , "Clear the play field"); - menu2->AppendSeparator(); - menu2->Append(IDM_EASY, _T("&Easy"), wxEmptyString, TRUE); // "10x10 play field", TRUE); - menu2->Append(IDM_MEDIUM, _T("&Medium"), wxEmptyString, TRUE); // "15x15 play field", TRUE); - menu2->Append(IDM_DIFFICULT, _T("&Difficult"), wxEmptyString, TRUE); // "25x20 play field", TRUE); - menuBar1->Append(menu2, _T("&Game")); - SetMenuBar(menuBar1); - menuBar=menuBar1; - menuBar->Check(wxGetApp().level, TRUE); - - // Create child subwindows. - BombsCanvas = new BombsCanvasClass(this); - - // Ensure the subwindows get resized o.k. -// OnSize(width, height); - - // Centre frame on the screen. - Centre(wxBOTH); - - // Show the frame. - Show(TRUE); -} + m_game = game; -BombsFrameClass::~BombsFrameClass(void) -{ -} + SetIcon(wxICON(bombs)); -void BombsFrameClass::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) -{ - this->Destroy(); +#if wxUSE_STATUSBAR + CreateStatusBar(); +#endif + + // Create a menu bar for the frame + wxMenuBar *menuBar = new wxMenuBar; + wxMenu *menuFile = new wxMenu; + wxMenu *menuLevel = new wxMenu; + menuLevel->AppendRadioItem(bombsID_EASY, wxT("&Easy (10x10)\tCtrl-1")); + menuLevel->AppendRadioItem(bombsID_MEDIUM, wxT("&Medium (15x15)\tCtrl-2")); + menuLevel->AppendRadioItem(bombsID_HARD, wxT("&Hard (25x20)\tCtrl-3")); + + menuFile->Append(bombsID_NEWGAME, wxT("&New Game"), + menuLevel, wxT("Starts a new game")); + + menuFile->AppendSeparator(); + menuFile->Append(wxID_EXIT, wxT("E&xit"), wxT("Quits the application")); + + menuBar->Append(menuFile, wxT("&File")); + + + wxMenu *menuHelp = new wxMenu; + menuHelp->Append(wxID_ABOUT, wxT("&About"), + wxT("Displays the program information") ); + + menuBar->Append(menuHelp, wxT("&Help")); + + SetMenuBar(menuBar); + + // Create child subwindows. + m_canvas = new BombsCanvas(this, m_game); + + // Ensure the subwindows get resized o.k. + // OnSize(width, height); + + // Centre frame on the screen. + Centre(wxBOTH); + + // Show the frame. + Show(); } -void BombsFrameClass::OnExit(wxCommandEvent& WXUNUSED(event)) +void BombsFrame::OnExit(wxCommandEvent& WXUNUSED(event)) { - this->Destroy(); + Close(); } -void BombsFrameClass::OnRestart(wxCommandEvent& WXUNUSED(event)) +void BombsFrame::NewGame(int level) { - BombsCanvas->UpdateFieldSize(); - int xmax=BombsCanvas->field_width*BombsCanvas->x_cell*X_UNIT; - int ymax=BombsCanvas->field_height*BombsCanvas->y_cell*Y_UNIT; - wxGetApp().BombsFrame->SetClientSize(xmax, ymax); + + int numHorzCells = 20, numVertCells = 20; + + switch(level) + { + case bombsID_EASY: + numHorzCells = numVertCells = 10; + break; + + case bombsID_MEDIUM: + numHorzCells = numVertCells = 15; + break; + + case bombsID_HARD: + numHorzCells = 25; numVertCells = 20; + break; + + default : + wxFAIL_MSG(wxT("Invalid level")); + break; + } + + m_game->Init(numHorzCells, numVertCells); + + GetMenuBar()->Check(level, true); + + m_canvas->UpdateGridSize(); + SetClientSize(m_canvas->GetGridSizeInPixels()); } -void BombsFrameClass::OnAbout(wxCommandEvent& WXUNUSED(event)) +void BombsFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { - wxMessageBox(_T("wxBombs (c) 1996 by P. Foggia\n"), _T("About wxBombs")); + wxMessageBox( + wxT("wxBombs (c) 1996 by P. Foggia\n"), + wxT("About wxBombs") ); } -void BombsFrameClass::OnEasy(wxCommandEvent& WXUNUSED(event)) +void BombsFrame::OnNewEasyGame(wxCommandEvent& WXUNUSED(event)) { - menuBar->Check(wxGetApp().level, FALSE); - wxGetApp().level=IDM_EASY; - menuBar->Check(wxGetApp().level, TRUE); + NewGame(bombsID_EASY); } -void BombsFrameClass::OnMedium(wxCommandEvent& WXUNUSED(event)) +void BombsFrame::OnNewMediumGame(wxCommandEvent& WXUNUSED(event)) { - menuBar->Check(wxGetApp().level, FALSE); - wxGetApp().level=IDM_MEDIUM; - menuBar->Check(wxGetApp().level, TRUE); + NewGame(bombsID_MEDIUM); } -void BombsFrameClass::OnDifficult(wxCommandEvent& WXUNUSED(event)) +void BombsFrame::OnNewHardGame(wxCommandEvent& WXUNUSED(event)) { - menuBar->Check(wxGetApp().level, FALSE); - wxGetApp().level=IDM_DIFFICULT; - menuBar->Check(wxGetApp().level, TRUE); + NewGame(bombsID_HARD); } -BEGIN_EVENT_TABLE(BombsCanvasClass, wxWindow) - EVT_PAINT(BombsCanvasClass::OnPaint) - EVT_MOUSE_EVENTS(BombsCanvasClass::OnEvent) +BEGIN_EVENT_TABLE(BombsCanvas, wxPanel) + EVT_PAINT(BombsCanvas::OnPaint) + EVT_MOUSE_EVENTS(BombsCanvas::OnMouseEvent) + EVT_CHAR(BombsCanvas::OnChar) END_EVENT_TABLE() -BombsCanvasClass::BombsCanvasClass(wxFrame *parent, const wxPoint& pos, const wxSize& size, long style): - wxWindow(parent, -1, pos, size, style) -{ - int sx, sy; - wxClientDC dc(this); - wxFont font= BOMBS_FONT; - dc.SetFont(font); +BombsCanvas::BombsCanvas(wxFrame *parent, BombsGame *game) + : wxPanel(parent, wxID_ANY) +{ + m_game = game; + int sx, sy; + wxClientDC dc(this); + wxFont font= BOMBS_FONT; + dc.SetFont(font); - long chw, chh; - wxChar buf[]=_T("M"); + long chw, chh; + wxString buf = wxT("M"); - dc.GetTextExtent(buf, &chw, &chh); - dc.SetFont(wxNullFont); + dc.GetTextExtent(buf, &chw, &chh); + dc.SetFont(wxNullFont); - dc.SetMapMode(wxMM_METRIC); + dc.SetMapMode(wxMM_METRIC); - int xcm = dc.LogicalToDeviceX(10); - int ycm = dc.LogicalToDeviceY(10); + int xcm = dc.LogicalToDeviceX(10); + int ycm = dc.LogicalToDeviceY(10); // To have a square cell, there must be : // sx*ycm == sy*xcm - if (chw*ycm < chh*xcm) - { sy=chh; - sx=chh*xcm/ycm; + if (chw*ycm < chh*xcm) + { + sy = chh; + sx = chh*xcm/ycm; } - else - { sx=chw; - sy=chw*ycm/xcm; + else + { + sx = chw; + sy = chw*ycm/xcm; } - x_cell = (sx+3+X_UNIT)/X_UNIT; - y_cell = (sy+3+Y_UNIT)/Y_UNIT; - dc.SetMapMode(wxMM_TEXT); - bmp=NULL; - UpdateFieldSize(); + + m_cellWidth = (sx+3+X_UNIT)/X_UNIT; + m_cellHeight = (sy+3+Y_UNIT)/Y_UNIT; + dc.SetMapMode(wxMM_TEXT); + m_bmp = NULL; } -BombsCanvasClass::~BombsCanvasClass(void) +BombsCanvas::~BombsCanvas() { - if (bmp) - delete bmp; + if (m_bmp) + { + delete m_bmp; + m_bmp = NULL; + } } // Called when canvas needs to be repainted. -void BombsCanvasClass::OnPaint(wxPaintEvent& WXUNUSED(event)) +void BombsCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { - wxPaintDC dc(this); - - // Insert your drawing code here. - if (!bmp) - { bmp=new wxBitmap(field_width*x_cell*X_UNIT+1, - field_height*y_cell*Y_UNIT+1); - if (bmp) - { wxMemoryDC memDC; - memDC.SelectObject(* bmp); - DrawField(&memDC, 0, 0, field_width-1, field_height-1); - memDC.SelectObject(wxNullBitmap); + wxPaintDC dc(this); + + const int numHorzCells = m_game->GetWidth(); + const int numVertCells = m_game->GetHeight(); + // Insert your drawing code here. + if (!m_bmp) + { + wxSize size = dc.GetSize(); + m_bmp = new wxBitmap(size.GetWidth(), size.GetHeight()); + if (m_bmp) + { + wxMemoryDC memDC; + memDC.SelectObject(*m_bmp); + DrawField(&memDC, 0, 0, numHorzCells-1, numVertCells-1); + memDC.SelectObject(wxNullBitmap); } } - if (bmp) - { wxMemoryDC memDC; - memDC.SelectObject(* bmp); - dc.Blit(0, 0, field_width*x_cell*X_UNIT+1, - field_height*y_cell*Y_UNIT+1, - &memDC, 0, 0, wxCOPY); + + if (m_bmp) + { + wxMemoryDC memDC; + memDC.SelectObject(*m_bmp); + wxSize size = dc.GetSize(); + dc.Blit(0, 0, size.GetWidth(), size.GetHeight(), + &memDC, 0, 0, wxCOPY); memDC.SelectObject(wxNullBitmap); } - else - DrawField(& dc, 0, 0, field_width-1, field_height-1); + else + { + DrawField(&dc, 0, 0, numHorzCells-1, numVertCells-1); + } +} + +void BombsCanvas::UpdateGridSize() +{ + + if (m_bmp) + { + delete m_bmp; + m_bmp = NULL; + } + + Refresh(); +} + +wxSize BombsCanvas::GetGridSizeInPixels() const +{ + return wxSize(m_cellWidth*X_UNIT*m_game->GetWidth(), + m_cellHeight*Y_UNIT*m_game->GetHeight()); } -// Updates the field size depending on wxGetApp().level and -// redraws the canvas -void BombsCanvasClass::UpdateFieldSize() - { field_width=20; - field_height=20; - - switch(wxGetApp().level) - { case IDM_EASY: - field_width=10; - field_height=10; - break; - case IDM_MEDIUM: - field_width=15; - field_height=15; - break; - case IDM_DIFFICULT: - field_width=25; - field_height=20; - break; - } - wxGetApp().Game.Init(field_width, field_height); - - if (bmp) - delete bmp; - bmp=NULL; - - wxWindow::Refresh(); - } diff --git a/demos/bombs/bombs.h b/demos/bombs/bombs.h index f34edc6c95..d56f528f0a 100644 --- a/demos/bombs/bombs.h +++ b/demos/bombs/bombs.h @@ -2,108 +2,107 @@ // Name: bombs.h // Purpose: Bombs game // Author: P. Foggia 1996 -// Modified by: +// Modified by: Wlodzimierz Skiba (ABX) 2003 // Created: 1996 // RCS-ID: $Id$ // Copyright: (c) 1996 P. Foggia // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// -#ifndef _INC_BOMBS_H -#define _INC_BOMBS_H +#ifndef _WX_DEMOS_BOMBS_BOMBS_H_ +#define _WX_DEMOS_BOMBS_BOMBS_H_ #include "game.h" -/* - * Forward declarations of all top-level window classes. - */ -class BombsFrameClass; -class AboutFrameClass; +class BombsFrame; /* * Class representing the entire Application */ -class AppClass: public wxApp +class BombsApp: public wxApp { - public: - BombsFrameClass *BombsFrame; - int level; - BombsGame Game; +public: + virtual bool OnInit(); + +private : + BombsFrame *m_frame; + + BombsGame m_game; - bool OnInit(); }; -DECLARE_APP(AppClass) +DECLARE_APP(BombsApp) -class BombsCanvasClass; +class BombsCanvas; -class BombsFrameClass: public wxFrame +class BombsFrame : public wxFrame { - private: - protected: - public: - // Subwindows for reference within the program. - BombsCanvasClass *BombsCanvas; - wxMenuBar *menuBar; - - // Constructor and destructor - BombsFrameClass(wxFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, long style); - ~BombsFrameClass(void); - - void OnCloseWindow(wxCloseEvent& event); - void OnExit(wxCommandEvent& event); - void OnRestart(wxCommandEvent& event); - void OnAbout(wxCommandEvent& event); - void OnEasy(wxCommandEvent& event); - void OnMedium(wxCommandEvent& event); - void OnDifficult(wxCommandEvent& event); - -DECLARE_EVENT_TABLE() +public: + + BombsFrame(BombsGame *bombsGame); + + void NewGame(int level); + +private: + + void OnNewEasyGame(wxCommandEvent& event); + void OnNewMediumGame(wxCommandEvent& event); + void OnNewHardGame(wxCommandEvent& event); + + void OnExit(wxCommandEvent& event); + + void OnAbout(wxCommandEvent& event); + + BombsGame *m_game; + + // Subwindows for reference within the program. + BombsCanvas *m_canvas; + + DECLARE_EVENT_TABLE() }; -/* Menu identifiers - */ -// File -#define BOMBSFRAMECLASS_FILE 1 -// E&xit -#define IDM_EXIT 2 -// About... -#define IDM_ABOUT 3 -// Game -#define BOMBSFRAMECLASS_GAME 4 -// &Restart -#define IDM_RESTART 5 -// &Easy -#define IDM_EASY 6 -// &Medium -#define IDM_MEDIUM 7 -// &Difficult -#define IDM_DIFFICULT 8 - -class BombsCanvasClass: public wxWindow +// App specific menu identifiers +enum { - private: - protected: - public: - int field_width, field_height; - int x_cell, y_cell; - wxBitmap *bmp; - // Constructor and destructor - BombsCanvasClass(wxFrame *parent, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0); - ~BombsCanvasClass(void); - - void OnPaint(wxPaintEvent& event); - void DrawField(wxDC *, int xc1, int yc1, int xc2, int yc2); - void RefreshField(int xc1, int yc1, int xc2, int yc2); - void Uncover(int x, int y); - void OnEvent(wxMouseEvent& event); - void UpdateFieldSize(); - -DECLARE_EVENT_TABLE() + bombsID_NEWGAME = wxID_HIGHEST, + bombsID_EASY, + bombsID_MEDIUM, + bombsID_HARD }; -/* Menu identifiers - */ +class BombsCanvas : public wxPanel +{ +public: + + // Constructor and destructor + + BombsCanvas(wxFrame *parent, BombsGame *game); + + void UpdateGridSize(); + + wxSize GetGridSizeInPixels() const; + + ~BombsCanvas(); + +private: + + void OnPaint(wxPaintEvent& event); + void DrawField(wxDC *, int xc1, int yc1, int xc2, int yc2); + void RefreshField(int xc1, int yc1, int xc2, int yc2); + void Uncover(int x, int y); + void OnMouseEvent(wxMouseEvent& event); + void OnChar(wxKeyEvent& event); + + BombsGame *m_game; + + wxBitmap *m_bmp; + + // Cell size in pixels + int m_cellWidth; + int m_cellHeight; + + DECLARE_EVENT_TABLE() +}; /* The following sizes should probably be redefined */ /* dimensions of a scroll unit, in pixels */ @@ -111,10 +110,14 @@ DECLARE_EVENT_TABLE() #define Y_UNIT 4 /* the dimensions of a cell, in scroll units are in - * BombsCanvasClass::x_cell and y_cell + * BombsCanvas::x_cell and y_cell */ +#ifdef __WXWINCE__ +#define BOMBS_FONT wxFont(12, wxSWISS, wxNORMAL, wxNORMAL) +#else #define BOMBS_FONT wxFont(14, wxROMAN, wxNORMAL, wxNORMAL) +#endif -#endif /* mutual exclusion */ +#endif // #ifndef _WX_DEMOS_BOMBS_BOMBS_H_ diff --git a/demos/bombs/bombs1.cpp b/demos/bombs/bombs1.cpp index fba51ace6e..cb1a9cc995 100644 --- a/demos/bombs/bombs1.cpp +++ b/demos/bombs/bombs1.cpp @@ -2,7 +2,7 @@ // Name: bombs1.cpp // Purpose: Bombs game // Author: P. Foggia 1996 -// Modified by: +// Modified by: Wlodzimierz Skiba (ABX) 2003 // Created: 1996 // RCS-ID: $Id$ // Copyright: (c) 1996 P. Foggia @@ -15,211 +15,335 @@ */ #ifdef __GNUG__ -#pragma implementation +# pragma implementation #endif #include "wx/wxprec.h" +#ifdef __BORLANDC__ +# pragma hdrstop +#endif + #ifndef WX_PRECOMP - #include "wx/wx.h" +# include "wx/wx.h" #endif //precompiled headers #include "bombs.h" -/*-------- BombCanvasClass::DrawField(dc, xc1, yc1, xc2, yc2) -------*/ -/* Draws the field on the device context dc */ -/* xc1,yc1 etc. are the (inclusive) limits of the area to be drawn, */ -/* expressed in cells. */ -/*---------------------------------------------------------------------*/ -void BombsCanvasClass::DrawField(wxDC *dc, int xc1, int yc1, int xc2, int yc2) -{ int x,y,xmax,ymax; - wxChar buf[2]; - long chw, chh; - - wxColour *wxBlack = wxTheColourDatabase->FindColour(_T("BLACK")); - wxColour *wxWhite = wxTheColourDatabase->FindColour(_T("WHITE")); - wxColour *wxRed = wxTheColourDatabase->FindColour(_T("RED")); - wxColour *wxBlue = wxTheColourDatabase->FindColour(_T("BLUE")); - wxColour *wxGrey = wxTheColourDatabase->FindColour(_T("LIGHT GREY")); - wxColour *wxGreen = wxTheColourDatabase->FindColour(_T("GREEN")); - - wxPen *blackPen = wxThePenList->FindOrCreatePen(*wxBlack, 1, wxSOLID); - wxPen *redPen = wxThePenList->FindOrCreatePen(*wxRed, 1, wxSOLID); - wxPen *bluePen = wxThePenList->FindOrCreatePen(*wxBlue, 1, wxSOLID); - wxBrush *whiteBrush = wxTheBrushList->FindOrCreateBrush(*wxWhite, wxSOLID); - wxBrush *greyBrush = wxTheBrushList->FindOrCreateBrush(*wxGrey, wxSOLID); - wxBrush *redBrush = wxTheBrushList->FindOrCreateBrush(*wxRed, wxSOLID); - - xmax=field_width*x_cell*X_UNIT; - ymax=field_height*y_cell*Y_UNIT; - - - dc->SetPen(* blackPen); - for(x=xc1; x<=xc2; x++) - dc->DrawLine(x*x_cell*X_UNIT, 0, x*x_cell*X_UNIT, ymax); - for(y=xc1; y<=yc2; y++) - dc->DrawLine(0, y*y_cell*Y_UNIT, xmax, y*y_cell*Y_UNIT); - - - wxFont font= BOMBS_FONT; - dc->SetFont(font); - - buf[1]=_T('\0'); - for(x=xc1; x<=xc2; x++) - for(y=yc1; y<=yc2; y++) - { if (wxGetApp().Game.IsMarked(x,y)) - { dc->SetPen(* blackPen); - dc->SetBrush(* greyBrush); - dc->DrawRectangle( x*x_cell*X_UNIT, y*y_cell*Y_UNIT, - x_cell*X_UNIT+1, y_cell*Y_UNIT+1); - *buf=_T('M'); - if (!wxGetApp().Game.IsHidden(x,y) && wxGetApp().Game.IsBomb(x,y)) - dc->SetTextForeground(*wxBlue); - else - dc->SetTextForeground(*wxRed); - dc->SetTextBackground(*wxGrey); - dc->GetTextExtent(buf, &chw, &chh); - dc->DrawText( buf, - x*x_cell*X_UNIT + (x_cell*X_UNIT-chw)/2, - y*y_cell*Y_UNIT + (y_cell*Y_UNIT-chh)/2 - ); - if (!wxGetApp().Game.IsHidden(x,y) && wxGetApp().Game.IsBomb(x,y)) - { dc->SetPen(*redPen); - dc->DrawLine(x*x_cell*X_UNIT, y*y_cell*Y_UNIT, - (x+1)*x_cell*X_UNIT, (y+1)*y_cell*Y_UNIT); - dc->DrawLine(x*x_cell*X_UNIT, (y+1)*y_cell*Y_UNIT, - (x+1)*x_cell*X_UNIT, y*y_cell*Y_UNIT); - } - } - else if (wxGetApp().Game.IsHidden(x,y)) - { dc->SetPen(*blackPen); - dc->SetBrush(*greyBrush); - dc->DrawRectangle( x*x_cell*X_UNIT, y*y_cell*Y_UNIT, - x_cell*X_UNIT+1, y_cell*Y_UNIT+1); - } - else if (wxGetApp().Game.IsBomb(x,y)) - { dc->SetPen(* blackPen); - dc->SetBrush(* redBrush); - dc->DrawRectangle( x*x_cell*X_UNIT, y*y_cell*Y_UNIT, - x_cell*X_UNIT+1, y_cell*Y_UNIT+1); - *buf=_T('B'); - dc->SetTextForeground(* wxBlack); - dc->SetTextBackground(* wxRed); - dc->GetTextExtent(buf, &chw, &chh); - dc->DrawText( buf, - x*x_cell*X_UNIT + (x_cell*X_UNIT-chw)/2, - y*y_cell*Y_UNIT + (y_cell*Y_UNIT-chh)/2 - ); - if (wxGetApp().Game.IsExploded(x,y)) - { dc->SetPen(* bluePen); - dc->DrawLine(x*x_cell*X_UNIT, y*y_cell*Y_UNIT, - (x+1)*x_cell*X_UNIT, (y+1)*y_cell*Y_UNIT); - dc->DrawLine(x*x_cell*X_UNIT, (y+1)*y_cell*Y_UNIT, - (x+1)*x_cell*X_UNIT, y*y_cell*Y_UNIT); - } - } - else // Display a digit - { dc->SetPen(* blackPen); - dc->SetBrush(* whiteBrush); - dc->DrawRectangle( x*x_cell*X_UNIT, y*y_cell*Y_UNIT, - x_cell*X_UNIT+1, y_cell*Y_UNIT+1); - *buf = (wxGetApp().Game.Get(x,y) & BG_MASK) + _T('0'); +// Draws the field on the device context dc +// xc1,yc1 etc. are the (inclusive) limits of the area to be drawn, +// expressed in cells. +void BombsCanvas::DrawField(wxDC *dc, int xc1, int yc1, int xc2, int yc2) +{ + wxString buf; + long chw, chh; + + wxColour wxBlack = wxTheColourDatabase->Find(wxT("BLACK")); + wxColour wxWhite = wxTheColourDatabase->Find(wxT("WHITE")); + wxColour wxRed = wxTheColourDatabase->Find(wxT("RED")); + wxColour wxBlue = wxTheColourDatabase->Find(wxT("BLUE")); + wxColour wxGrey = wxTheColourDatabase->Find(wxT("LIGHT GREY")); + wxColour wxFocused = wxTheColourDatabase->Find(wxT("GREY")); + wxColour wxGreen = wxTheColourDatabase->Find(wxT("GREEN")); + + wxPen *blackPen = wxThePenList->FindOrCreatePen(wxBlack, 1, wxSOLID); + wxPen *redPen = wxThePenList->FindOrCreatePen(wxRed, 1, wxSOLID); + wxPen *bluePen = wxThePenList->FindOrCreatePen(wxBlue, 1, wxSOLID); + wxBrush *whiteBrush = wxTheBrushList->FindOrCreateBrush(wxWhite, wxSOLID); + wxBrush *greyBrush = wxTheBrushList->FindOrCreateBrush(wxGrey, wxSOLID); + wxBrush *focusedBrush = wxTheBrushList->FindOrCreateBrush(wxFocused, wxSOLID); + wxBrush *redBrush = wxTheBrushList->FindOrCreateBrush(wxRed, wxSOLID); + + dc->SetPen(* blackPen); + + int x, y; + int xMax = this->GetGridSizeInPixels().GetWidth(); + int yMax = this->GetGridSizeInPixels().GetHeight(); + for(x=xc1; x<=xc2; x++) + dc->DrawLine(x*m_cellWidth*X_UNIT, 0, x*m_cellWidth*X_UNIT, yMax); + for(y=xc1; y<=yc2; y++) + dc->DrawLine(0, y*m_cellHeight*Y_UNIT, xMax, y*m_cellHeight*Y_UNIT); + + + wxFont font= BOMBS_FONT; + dc->SetFont(font); + + for(x=xc1; x<=xc2; x++) + for(y=yc1; y<=yc2; y++) + { + if (m_game->IsMarked(x,y)) + { + dc->SetPen(* blackPen); + + if (m_game->IsFocussed(x, y)) + dc->SetBrush(* focusedBrush); + else + dc->SetBrush(* greyBrush); + + dc->DrawRectangle( x*m_cellWidth*X_UNIT, y*m_cellHeight*Y_UNIT, + m_cellWidth*X_UNIT+1, m_cellHeight*Y_UNIT+1); + buf = wxT("M"); + if (!m_game->IsHidden(x,y) && m_game->IsBomb(x,y)) + dc->SetTextForeground(wxBlue); + else + dc->SetTextForeground(wxRed); + + dc->SetTextBackground(wxGrey); + dc->GetTextExtent(buf, &chw, &chh); + dc->DrawText( buf, + x*m_cellWidth*X_UNIT + (m_cellWidth*X_UNIT-chw)/2, + y*m_cellHeight*Y_UNIT + (m_cellHeight*Y_UNIT-chh)/2 ); + + if (!m_game->IsHidden(x,y) && m_game->IsBomb(x,y)) + { + dc->SetPen(*redPen); + dc->DrawLine(x*m_cellWidth*X_UNIT, y*m_cellHeight*Y_UNIT, + (x+1)*m_cellWidth*X_UNIT, (y+1)*m_cellHeight*Y_UNIT); + dc->DrawLine(x*m_cellWidth*X_UNIT, (y+1)*m_cellHeight*Y_UNIT, + (x+1)*m_cellWidth*X_UNIT, y*m_cellHeight*Y_UNIT); + } + } + else if (m_game->IsHidden(x,y)) + { + dc->SetPen(*blackPen); + if (m_game->IsFocussed(x, y)) + dc->SetBrush(* focusedBrush); + else + dc->SetBrush(*greyBrush); + + dc->DrawRectangle( x*m_cellWidth*X_UNIT, y*m_cellHeight*Y_UNIT, + m_cellWidth*X_UNIT+1, m_cellHeight*Y_UNIT+1); + } + else if (m_game->IsBomb(x,y)) + { + dc->SetPen(* blackPen); + dc->SetBrush(* redBrush); + dc->DrawRectangle( x*m_cellWidth*X_UNIT, y*m_cellHeight*Y_UNIT, + m_cellWidth*X_UNIT+1, m_cellHeight*Y_UNIT+1); + buf = wxT("B"); + dc->SetTextForeground(wxBlack); + dc->SetTextBackground(wxRed); + dc->GetTextExtent(buf, &chw, &chh); + dc->DrawText( buf, + x*m_cellWidth*X_UNIT + (m_cellWidth*X_UNIT-chw)/2, + y*m_cellHeight*Y_UNIT + (m_cellHeight*Y_UNIT-chh)/2); + if (m_game->IsExploded(x,y)) + { + dc->SetPen(* bluePen); + dc->DrawLine(x*m_cellWidth*X_UNIT, y*m_cellHeight*Y_UNIT, + (x+1)*m_cellWidth*X_UNIT, (y+1)*m_cellHeight*Y_UNIT); + dc->DrawLine(x*m_cellWidth*X_UNIT, (y+1)*m_cellHeight*Y_UNIT, + (x+1)*m_cellWidth*X_UNIT, y*m_cellHeight*Y_UNIT); + } + } + else // Display a digit + { + dc->SetPen(* blackPen); + if (m_game->IsFocussed(x, y)) + dc->SetBrush(* focusedBrush); + else + dc->SetBrush(* whiteBrush); + dc->DrawRectangle( x*m_cellWidth*X_UNIT, y*m_cellHeight*Y_UNIT, + m_cellWidth*X_UNIT+1, m_cellHeight*Y_UNIT+1); + + int digit_value = m_game->Get(x,y) & BG_MASK; + switch(digit_value) + { + case 0: + buf = wxT("0"); + dc->SetTextForeground(wxGreen); + break; + case 1: + buf = wxT("1"); + dc->SetTextForeground(wxBlue); + break; + default: + buf.Printf(wxT("%d"),digit_value); + dc->SetTextForeground(wxBlack); + break; + } dc->GetTextExtent(buf, &chw, &chh); - switch(*buf) - { case _T('0'): dc->SetTextForeground(* wxGreen); break; - case _T('1'): dc->SetTextForeground(* wxBlue); break; - default: dc->SetTextForeground(* wxBlack); break; - } - dc->SetTextBackground(* wxWhite); + dc->SetTextBackground(wxWhite); dc->DrawText( buf, - x*x_cell*X_UNIT + (x_cell*X_UNIT-chw)/2, - y*y_cell*Y_UNIT + (y_cell*Y_UNIT-chh)/2 - ); - } - } - dc->SetFont(wxNullFont); - - if (wxGetApp().BombsFrame) - { wxString buf; - buf.Printf(_T("%d bombs %d remaining cells"), - wxGetApp().Game.GetBombs(), - wxGetApp().Game.GetRemainingCells()); - wxGetApp().BombsFrame->SetStatusText(buf, 0); + x*m_cellWidth*X_UNIT + (m_cellWidth*X_UNIT-chw)/2, + y*m_cellHeight*Y_UNIT + (m_cellHeight*Y_UNIT-chh)/2); + } } + dc->SetFont(wxNullFont); + +#if wxUSE_LOG + wxLogStatus(wxT("%d bombs %d remaining cells"), + m_game->GetNumBombs(), m_game->GetNumRemainingCells() ); +#endif } -/*-------- BombCanvasClass::RefreshField(xc1, yc1, xc2, yc2) --------*/ -/* Refreshes the field image */ -/* xc1,yc1 etc. are the (inclusive) limits of the area to be drawn, */ -/* expressed in cells. */ -/*---------------------------------------------------------------------*/ -void BombsCanvasClass::RefreshField(int xc1, int yc1, int xc2, int yc2) - { +// Refreshes the field image +// xc1,yc1 etc. are the (inclusive) limits of the area to be drawn, +// expressed in cells. +void BombsCanvas::RefreshField(int xc1, int yc1, int xc2, int yc2) +{ wxClientDC dc(this); DrawField(& dc, xc1, yc1, xc2, yc2); - if (bmp) - { wxMemoryDC memDC; - memDC.SelectObject(* bmp); + if (m_bmp) + { + wxMemoryDC memDC; + memDC.SelectObject(*m_bmp); DrawField(&memDC, xc1, yc1, xc2, yc2); memDC.SelectObject(wxNullBitmap); - } - } + } +} // Called when uncovering a cell. -void BombsCanvasClass::Uncover(int x, int y) +void BombsCanvas::Uncover(int x, int y) { - wxGetApp().Game.Unhide(x,y); - RefreshField(x, y, x, y); - if (wxGetApp().Game.IsBomb(x,y) || wxGetApp().Game.GetRemainingCells()==0) - { wxBell(); - if (!wxGetApp().Game.IsBomb(x,y)) - { wxMessageBox(_T("Nice! You found all the bombs!"), _T("wxWin Bombs"), - wxOK|wxCENTRE, wxGetApp().BombsFrame); - } - else // x,y is a bomb - { wxGetApp().Game.Explode(x, y); - } - for(x=0; xUnhide(x,y); + RefreshField(x, y, x, y); + + const int gridWidth = m_game->GetWidth(); + const int gridHeight = m_game->GetHeight(); + + const bool hasWon = m_game->GetNumRemainingCells() == 0; + if (m_game->IsBomb(x,y) || hasWon) + { + wxBell(); + if (hasWon) + { + wxMessageBox(wxT("Nice! You found all the bombs!"), + wxT("wxWin Bombs"), wxOK|wxCENTRE); + } + else // x,y is a bomb + { + m_game->Explode(x, y); + } + + for(x=0; xUnhide(x,y); + RefreshField(0, 0, gridWidth-1, gridHeight-1); } - else if (!wxGetApp().Game.Get(x, y)) - { int left = ( x > 0 ) ? x-1 : 0; - int right = ( x < wxGetApp().Game.GetWidth() - 1 )? - x+1 : wxGetApp().Game.GetWidth() - 1; - int top = ( y > 0 ) ? y-1 : 0; - int bottom = ( y < wxGetApp().Game.GetHeight() - 1 )? - y+1 : wxGetApp().Game.GetHeight() - 1; - int i,j; - for (j = top; j <= bottom; j++) - for (i=left; i <= right; i++) - if ((i != x || j != y) && wxGetApp().Game.IsHidden(i,j) - && !wxGetApp().Game.IsMarked(i,j)) - Uncover(i,j); + else if (!m_game->Get(x, y)) + { + int left = ( x > 0 ) ? x-1 : 0; + int right = ( x < gridWidth - 1 ) + ? x+1 + : gridWidth - 1; + int top = ( y > 0 ) ? y-1 : 0; + int bottom = ( y < gridHeight - 1 ) + ? y+1 + : gridHeight - 1; + + int i, j; + for (j=top; j<=bottom; j++) + for (i=left; i<=right; i++) + if ( (i != x || j != y) && m_game->IsHidden(i, j) + && !m_game->IsMarked(i, j) ) + { + Uncover(i, j); + } } } // Called when the canvas receives a mouse event. -void BombsCanvasClass::OnEvent(wxMouseEvent& event) +void BombsCanvas::OnMouseEvent(wxMouseEvent& event) { - wxCoord fx, fy; - event.GetPosition(&fx, &fy); - int x = fx/(x_cell*X_UNIT); - int y = fy/(y_cell*Y_UNIT); - if (xGetWidth(); + const int gridHeight = m_game->GetHeight(); + + wxCoord fx, fy; + event.GetPosition(&fx, &fy); + int x = fx/(m_cellWidth*X_UNIT); + int y = fy/(m_cellHeight*Y_UNIT); + if (xIsHidden(x,y) + || !m_game->GetNumRemainingCells() ) ) + { + // store previous and current field + int prevFocusX = m_game->m_gridFocusX; + int prevFocusY = m_game->m_gridFocusY; + m_game->m_gridFocusX = x; + m_game->m_gridFocusY = y; + RefreshField(prevFocusX, prevFocusY, prevFocusX, prevFocusY); + m_game->Mark(x, y); + RefreshField(x, y, x, y); + return; } - else if (event.LeftDown() && wxGetApp().Game.IsHidden(x,y) - && !wxGetApp().Game.IsMarked(x,y)) - { Uncover(x,y); - return; + else if (event.LeftDown() && m_game->IsHidden(x,y) + && !m_game->IsMarked(x,y)) + { + // store previous and current field + int prevGridFocusX = m_game->m_gridFocusX; + int prevGridFocusY = m_game->m_gridFocusY; + m_game->m_gridFocusX = x; + m_game->m_gridFocusY = y; + RefreshField(prevGridFocusX, prevGridFocusY, + prevGridFocusX, prevGridFocusY); + Uncover(x, y); + return; } } } +void BombsCanvas::OnChar(wxKeyEvent& event) +{ + int keyCode = event.GetKeyCode(); + int prevGridFocusX = m_game->m_gridFocusX; + int prevGridFocusY = m_game->m_gridFocusY; + + const int gridWidth = m_game->GetWidth(); + const int gridHeight = m_game->GetHeight(); + + switch(keyCode) + { + + case WXK_RIGHT: + m_game->m_gridFocusX++; + if (m_game->m_gridFocusX >= gridWidth) m_game->m_gridFocusX = 0; + break; + + case WXK_LEFT: + m_game->m_gridFocusX--; + if (m_game->m_gridFocusX<0) m_game->m_gridFocusX = gridWidth-1; + break; + + case WXK_DOWN: + m_game->m_gridFocusY++; + if (m_game->m_gridFocusY >= gridHeight) m_game->m_gridFocusY = 0; + break; + + case WXK_UP: + m_game->m_gridFocusY--; + if (m_game->m_gridFocusY<0) m_game->m_gridFocusY = gridHeight-1; + break; + + case WXK_RETURN: + if ( (prevGridFocusX == m_game->m_gridFocusX) + && (prevGridFocusY == m_game->m_gridFocusY) + && (m_game->IsHidden(m_game->m_gridFocusX, m_game->m_gridFocusY)) ) + { + m_game->Mark(m_game->m_gridFocusX, m_game->m_gridFocusY); + if (!m_game->IsMarked(m_game->m_gridFocusX, m_game->m_gridFocusY)) + { + Uncover(m_game->m_gridFocusX, m_game->m_gridFocusY); + } + RefreshField(m_game->m_gridFocusX, m_game->m_gridFocusY, + m_game->m_gridFocusX, m_game->m_gridFocusY); + } + break; + + default: + event.Skip(); + + } + + if ((prevGridFocusX != m_game->m_gridFocusX) + || (prevGridFocusY != m_game->m_gridFocusY)) + { + // refresh previous field and focused field + RefreshField(prevGridFocusX, prevGridFocusY, + prevGridFocusX, prevGridFocusY); + RefreshField(m_game->m_gridFocusX, m_game->m_gridFocusY, + m_game->m_gridFocusX, m_game->m_gridFocusY); + } +} diff --git a/demos/bombs/game.cpp b/demos/bombs/game.cpp index d49b6a434d..3778780869 100644 --- a/demos/bombs/game.cpp +++ b/demos/bombs/game.cpp @@ -2,7 +2,7 @@ // Name: bombs1.cpp // Purpose: Implementation of the class BombsGame // Author: P. Foggia 1996 -// Modified by: +// Modified by: Wlodzimierz Skiba (ABX) 2003 // Created: 1996 // RCS-ID: $Id$ // Copyright: (c) 1996 P. Foggia @@ -10,14 +10,18 @@ /////////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ -#pragma implementation +# pragma implementation #endif #include "wx/wxprec.h" +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + #ifndef WX_PRECOMP - #include "wx/wx.h" -#endif //precompiled headers +# include "wx/wx.h" +#endif #include "game.h" #include @@ -26,80 +30,92 @@ #define PROB 0.2 #ifndef RAND_MAX -#define RAND_MAX INT_MAX +# define RAND_MAX INT_MAX #endif -/*-------------------- BombsGame::~BombsGame() ---------------------*/ -/*--------------------------------------------------------------------*/ BombsGame::~BombsGame() - { if (field) - free(field); - } - -/*------------------ int BombsGame::Init(width,height) -------------------*/ -/* Initialize the play field. Returns 0 on failure */ -/*--------------------------------------------------------------------------*/ -int BombsGame::Init(int aWidth, int aHeight) - { int x, y; +{ + if (m_field) + { + delete[] m_field; + } +} + +// Initialize the play field. Returns false on failure +bool BombsGame::Init(int aWidth, int aHeight) +{ + m_gridFocusX = m_gridFocusY = -1; + + int x, y; int xx, yy; - if (field) - free(field); - field=(short *)malloc(aWidth*aHeight*sizeof(short)); - if (!field) - { width=height=0; - return 0; - } - width=aWidth; - height=aHeight; - - for(x=0; x=0 && xx=0 && yy=0 && xx=0 && yy class BombsGame - { protected: - int width,height; - short *field; - int bombs,normal_cells; - public: - BombsGame() { width=height=0; field=NULL; }; - ~BombsGame(); - int Init(int width, int height); - int GetWidth() { return width; }; - int GetHeight() { return height; }; - int Get(int x, int y) { return field[x+y*width]; }; - void Mark(int x, int y); - void Unhide(int x, int y); - void Explode(int x, int y); - int IsHidden(int x, int y) { return Get(x,y) & BG_HIDDEN; }; - int IsMarked(int x, int y) { return Get(x,y) & BG_MARKED; }; - int IsBomb(int x, int y) { return Get(x,y) & BG_BOMB; }; - int IsExploded(int x, int y) { return Get(x,y) & BG_EXPLODED; }; - int GetBombs() { return bombs; }; - int GetRemainingCells() { return normal_cells; }; - }; - -#endif /* def GAME_H */ +{ +public: + BombsGame() + { + m_width = m_height = 0; + m_field = NULL; + }; + + ~BombsGame(); + + int GetWidth() const { return m_width; }; + int GetHeight() const { return m_height; }; + + int Get(int x, int y) const + { + return m_field[x+y*m_width]; + }; + + int IsFocussed(int x, int y) const + { + return (m_gridFocusX == x) && (m_gridFocusY == y); + } + + int IsHidden(int x, int y) const + { + return Get(x,y) & BG_HIDDEN; + }; + + int IsMarked(int x, int y) const + { + return Get(x,y) & BG_MARKED; + }; + + int IsBomb(int x, int y) const + { + return Get(x,y) & BG_BOMB; + }; + + int IsExploded(int x, int y) const + { + return Get(x,y) & BG_EXPLODED; + }; + + int GetNumBombs() const + { + return m_numBombCells; + }; + + int GetNumRemainingCells() const + { + return m_numRemainingCells; + }; + + + + bool Init(int width, int height); + + + // Marks/unmarks a cell + void Mark(int x, int y); + + // Unhides a cell + void Unhide(int x, int y); + + // Makes a cell exploded + void Explode(int x, int y); + + int m_gridFocusX; + int m_gridFocusY; + +private: + + // Current difficulty level (Determines grid size). + //int m_level; + + int m_width, m_height; + short *m_field; + int m_numBombCells, m_numRemainingCells; + +}; +#endif // #ifndef _WX_DEMOS_BOMBS_GAME_H_ -- 2.45.2