]> git.saurik.com Git - wxWidgets.git/blame - demos/bombs/bombs.cpp
Fixes to allow compilation with no wchar_t (djgpp probably has a real wchar_t
[wxWidgets.git] / demos / bombs / bombs.cpp
CommitLineData
025e88c5
JS
1///////////////////////////////////////////////////////////////////////////////
2// Name: bombs.cpp
3// Purpose: Bombs game
4// Author: P. Foggia 1996
0c65afdb 5// Modified by: Wlodzimierz Skiba (ABX) 2003
025e88c5
JS
6// Created: 1996
7// RCS-ID: $Id$
8// Copyright: (c) 1996 P. Foggia
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
0c65afdb 13# pragma implementation
025e88c5
JS
14#endif
15
16#include "wx/wxprec.h"
17
0c65afdb
DS
18#ifdef __BORLANDC__
19# pragma hdrstop
20#endif
21
025e88c5 22#ifndef WX_PRECOMP
0c65afdb 23# include "wx/wx.h"
025e88c5
JS
24#endif //precompiled headers
25
6759ff7d
WS
26#include "wx/stockitem.h"
27
025e88c5
JS
28#include "bombs.h"
29
025e88c5
JS
30#include <stdlib.h>
31
0c65afdb
DS
32#ifndef __WXWINCE__
33# include <time.h>
34#endif
35
36#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) \
37 || defined(__WXMAC__) || defined(__WXMGL__)
38# include "bombs.xpm"
025e88c5
JS
39#endif
40
0c65afdb
DS
41IMPLEMENT_APP(BombsApp)
42
43#ifdef __WXWINCE__
44 STDAPI_(__int64) CeGetRandomSeed();
45#endif
025e88c5
JS
46
47// Called to initialize the program
0c65afdb 48bool BombsApp::OnInit()
025e88c5 49{
0c65afdb
DS
50#ifdef __WXWINCE__
51 srand((unsigned) CeGetRandomSeed());
52#else
53 srand((unsigned) time(NULL));
54#endif
025e88c5 55
0c65afdb 56 m_frame = new BombsFrame(&m_game);
025e88c5 57
23290a8c 58 m_frame->NewGame(bombsID_EASY, false);
025e88c5 59
0c65afdb 60 return true;
025e88c5
JS
61}
62
0c65afdb
DS
63BEGIN_EVENT_TABLE(BombsFrame, wxFrame)
64 EVT_MENU(bombsID_EASY, BombsFrame::OnNewEasyGame)
65 EVT_MENU(bombsID_MEDIUM, BombsFrame::OnNewMediumGame)
66 EVT_MENU(bombsID_HARD, BombsFrame::OnNewHardGame)
67 EVT_MENU(wxID_EXIT, BombsFrame::OnExit)
68 EVT_MENU(wxID_ABOUT, BombsFrame::OnAbout)
025e88c5
JS
69END_EVENT_TABLE()
70
0c65afdb
DS
71BombsFrame::BombsFrame(BombsGame *game)
72 : wxFrame(NULL, wxID_ANY, wxT("wxBombs"), wxDefaultPosition,
73 wxSize(300, 300), wxDEFAULT_DIALOG_STYLE|wxMINIMIZE_BOX)
025e88c5 74{
0c65afdb 75 m_game = game;
025e88c5 76
0c65afdb 77 SetIcon(wxICON(bombs));
025e88c5 78
0c65afdb
DS
79#if wxUSE_STATUSBAR
80 CreateStatusBar();
81#endif
82
83 // Create a menu bar for the frame
84 wxMenuBar *menuBar = new wxMenuBar;
85 wxMenu *menuFile = new wxMenu;
86 wxMenu *menuLevel = new wxMenu;
87 menuLevel->AppendRadioItem(bombsID_EASY, wxT("&Easy (10x10)\tCtrl-1"));
88 menuLevel->AppendRadioItem(bombsID_MEDIUM, wxT("&Medium (15x15)\tCtrl-2"));
89 menuLevel->AppendRadioItem(bombsID_HARD, wxT("&Hard (25x20)\tCtrl-3"));
90
91 menuFile->Append(bombsID_NEWGAME, wxT("&New Game"),
92 menuLevel, wxT("Starts a new game"));
93
94 menuFile->AppendSeparator();
6759ff7d 95 menuFile->Append(wxID_EXIT, wxGetStockLabel(wxID_EXIT), wxT("Quits the application"));
0c65afdb
DS
96
97 menuBar->Append(menuFile, wxT("&File"));
98
99
100 wxMenu *menuHelp = new wxMenu;
101 menuHelp->Append(wxID_ABOUT, wxT("&About"),
102 wxT("Displays the program information") );
103
104 menuBar->Append(menuHelp, wxT("&Help"));
105
106 SetMenuBar(menuBar);
107
108 // Create child subwindows.
109 m_canvas = new BombsCanvas(this, m_game);
110
111 // Ensure the subwindows get resized o.k.
112 // OnSize(width, height);
113
114 // Centre frame on the screen.
115 Centre(wxBOTH);
116
117 // Show the frame.
118 Show();
025e88c5
JS
119}
120
0c65afdb 121void BombsFrame::OnExit(wxCommandEvent& WXUNUSED(event))
025e88c5 122{
0c65afdb 123 Close();
025e88c5
JS
124}
125
23290a8c 126void BombsFrame::NewGame(int level, bool query)
025e88c5 127{
23290a8c
JS
128 if(query)
129 {
130 int ok = wxMessageBox(
131 wxT("Start new game regardless previous board?"),
132 wxT("Confirm"),
133 wxYES_NO | wxICON_QUESTION,
134 this
135 );
136 if(ok!=wxYES)return;
137 }
0c65afdb
DS
138
139 int numHorzCells = 20, numVertCells = 20;
140
141 switch(level)
142 {
143 case bombsID_EASY:
144 numHorzCells = numVertCells = 10;
145 break;
146
147 case bombsID_MEDIUM:
148 numHorzCells = numVertCells = 15;
149 break;
150
151 case bombsID_HARD:
152 numHorzCells = 25; numVertCells = 20;
153 break;
154
155 default :
156 wxFAIL_MSG(wxT("Invalid level"));
157 break;
158 }
159
160 m_game->Init(numHorzCells, numVertCells);
161
162 GetMenuBar()->Check(level, true);
163
164 m_canvas->UpdateGridSize();
165 SetClientSize(m_canvas->GetGridSizeInPixels());
025e88c5
JS
166}
167
0c65afdb 168void BombsFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
025e88c5 169{
0c65afdb
DS
170 wxMessageBox(
171 wxT("wxBombs (c) 1996 by P. Foggia\n<foggia@amalfi.dis.unina.it>"),
172 wxT("About wxBombs") );
025e88c5
JS
173}
174
0c65afdb 175void BombsFrame::OnNewEasyGame(wxCommandEvent& WXUNUSED(event))
025e88c5 176{
23290a8c 177 NewGame(bombsID_EASY, true);
025e88c5
JS
178}
179
0c65afdb 180void BombsFrame::OnNewMediumGame(wxCommandEvent& WXUNUSED(event))
025e88c5 181{
23290a8c 182 NewGame(bombsID_MEDIUM, true);
025e88c5
JS
183}
184
0c65afdb 185void BombsFrame::OnNewHardGame(wxCommandEvent& WXUNUSED(event))
025e88c5 186{
23290a8c 187 NewGame(bombsID_HARD, true);
025e88c5
JS
188}
189
0c65afdb
DS
190BEGIN_EVENT_TABLE(BombsCanvas, wxPanel)
191 EVT_PAINT(BombsCanvas::OnPaint)
192 EVT_MOUSE_EVENTS(BombsCanvas::OnMouseEvent)
193 EVT_CHAR(BombsCanvas::OnChar)
025e88c5
JS
194END_EVENT_TABLE()
195
0c65afdb
DS
196BombsCanvas::BombsCanvas(wxFrame *parent, BombsGame *game)
197 : wxPanel(parent, wxID_ANY)
198{
199 m_game = game;
200 int sx, sy;
201 wxClientDC dc(this);
202 wxFont font= BOMBS_FONT;
203 dc.SetFont(font);
025e88c5 204
0c65afdb
DS
205 long chw, chh;
206 wxString buf = wxT("M");
025e88c5 207
0c65afdb
DS
208 dc.GetTextExtent(buf, &chw, &chh);
209 dc.SetFont(wxNullFont);
025e88c5 210
0c65afdb 211 dc.SetMapMode(wxMM_METRIC);
025e88c5 212
0c65afdb
DS
213 int xcm = dc.LogicalToDeviceX(10);
214 int ycm = dc.LogicalToDeviceY(10);
025e88c5
JS
215 // To have a square cell, there must be :
216 // sx*ycm == sy*xcm
0c65afdb
DS
217 if (chw*ycm < chh*xcm)
218 {
219 sy = chh;
220 sx = chh*xcm/ycm;
025e88c5 221 }
0c65afdb
DS
222 else
223 {
224 sx = chw;
225 sy = chw*ycm/xcm;
025e88c5 226 }
0c65afdb
DS
227
228 m_cellWidth = (sx+3+X_UNIT)/X_UNIT;
229 m_cellHeight = (sy+3+Y_UNIT)/Y_UNIT;
230 dc.SetMapMode(wxMM_TEXT);
231 m_bmp = NULL;
025e88c5
JS
232}
233
0c65afdb 234BombsCanvas::~BombsCanvas()
025e88c5 235{
0c65afdb
DS
236 if (m_bmp)
237 {
238 delete m_bmp;
239 m_bmp = NULL;
240 }
025e88c5
JS
241}
242
243// Called when canvas needs to be repainted.
0c65afdb 244void BombsCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
025e88c5 245{
0c65afdb
DS
246 wxPaintDC dc(this);
247
248 const int numHorzCells = m_game->GetWidth();
249 const int numVertCells = m_game->GetHeight();
250 // Insert your drawing code here.
251 if (!m_bmp)
252 {
253 wxSize size = dc.GetSize();
254 m_bmp = new wxBitmap(size.GetWidth(), size.GetHeight());
255 if (m_bmp)
256 {
257 wxMemoryDC memDC;
258 memDC.SelectObject(*m_bmp);
259 DrawField(&memDC, 0, 0, numHorzCells-1, numVertCells-1);
260 memDC.SelectObject(wxNullBitmap);
025e88c5
JS
261 }
262 }
0c65afdb
DS
263
264 if (m_bmp)
265 {
266 wxMemoryDC memDC;
267 memDC.SelectObject(*m_bmp);
268 wxSize size = dc.GetSize();
269 dc.Blit(0, 0, size.GetWidth(), size.GetHeight(),
270 &memDC, 0, 0, wxCOPY);
025e88c5
JS
271 memDC.SelectObject(wxNullBitmap);
272 }
0c65afdb
DS
273 else
274 {
275 DrawField(&dc, 0, 0, numHorzCells-1, numVertCells-1);
276 }
277}
278
279void BombsCanvas::UpdateGridSize()
280{
281
282 if (m_bmp)
283 {
284 delete m_bmp;
285 m_bmp = NULL;
286 }
d2fc28b1 287 SetSize(GetGridSizeInPixels());
0c65afdb
DS
288 Refresh();
289}
290
291wxSize BombsCanvas::GetGridSizeInPixels() const
292{
293 return wxSize(m_cellWidth*X_UNIT*m_game->GetWidth(),
294 m_cellHeight*Y_UNIT*m_game->GetHeight());
025e88c5
JS
295}
296