Commit | Line | Data |
---|---|---|
a3f2380f JT |
1 | /* |
2 | * WineMine (main.c) | |
9a624916 | 3 | * |
5c4caa66 | 4 | * Copyright 2000 Joshua Thielen |
0799c1a7 AJ |
5 | * |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2.1 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
360a3f91 | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
a3f2380f JT |
19 | */ |
20 | ||
a9f96938 MM |
21 | #define WIN32_LEAN_AND_MEAN |
22 | ||
a3f2380f JT |
23 | #include <string.h> |
24 | #include <time.h> | |
25 | #include <windows.h> | |
a9f96938 | 26 | #include <stdlib.h> |
f20651b1 | 27 | #include <shellapi.h> |
a3f2380f | 28 | #include "main.h" |
a3f2380f JT |
29 | #include "resource.h" |
30 | ||
d38caa48 JC |
31 | #include <wine/debug.h> |
32 | ||
33 | WINE_DEFAULT_DEBUG_CHANNEL(winemine); | |
a3f2380f | 34 | |
f9026f4e | 35 | static const DWORD wnd_style = WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX; |
9111d07d | 36 | static const char* registry_key = "Software\\Microsoft\\WinMine"; |
f9026f4e RC |
37 | |
38 | ||
eec04aeb | 39 | void CheckLevel( BOARD *p_board ) |
a3f2380f | 40 | { |
eec04aeb FG |
41 | if( p_board->rows < BEGINNER_ROWS ) |
42 | p_board->rows = BEGINNER_ROWS; | |
a3f2380f | 43 | |
eec04aeb FG |
44 | if( p_board->rows > MAX_ROWS ) |
45 | p_board->rows = MAX_ROWS; | |
a3f2380f | 46 | |
eec04aeb FG |
47 | if( p_board->cols < BEGINNER_COLS ) |
48 | p_board->cols = BEGINNER_COLS; | |
a3f2380f | 49 | |
eec04aeb FG |
50 | if( p_board->cols > MAX_COLS ) |
51 | p_board->cols = MAX_COLS; | |
9a624916 | 52 | |
eec04aeb FG |
53 | if( p_board->mines < BEGINNER_MINES ) |
54 | p_board->mines = BEGINNER_MINES; | |
9a624916 | 55 | |
14c68c3c AJ |
56 | if( p_board->mines > ( p_board->cols - 1 ) * ( p_board->rows - 1 ) ) |
57 | p_board->mines = ( p_board->cols - 1 ) * ( p_board->rows - 1 ); | |
a3f2380f JT |
58 | } |
59 | ||
b82caec7 | 60 | static void LoadBoard( BOARD *p_board ) |
a3f2380f JT |
61 | { |
62 | DWORD size; | |
63 | DWORD type; | |
64 | HKEY hkey; | |
b599f89a | 65 | char data[MAX_PLAYER_NAME_SIZE+1]; |
a3f2380f JT |
66 | char key_name[8]; |
67 | unsigned i; | |
68 | ||
f9026f4e | 69 | RegOpenKeyEx( HKEY_CURRENT_USER, registry_key, |
a3f2380f | 70 | 0, KEY_QUERY_VALUE, &hkey ); |
9a624916 | 71 | |
9111d07d | 72 | size = sizeof( p_board->pos.x ); |
409fb90a MS |
73 | if( !RegQueryValueEx( hkey, "Xpos", NULL, &type, |
74 | (LPBYTE) &p_board->pos.x, &size ) == ERROR_SUCCESS ) | |
f9026f4e | 75 | p_board->pos.x = 0; |
a3f2380f | 76 | |
9111d07d | 77 | size = sizeof( p_board->pos.y ); |
409fb90a MS |
78 | if( !RegQueryValueEx( hkey, "Ypos", NULL, &type, |
79 | (LPBYTE) &p_board->pos.y, &size ) == ERROR_SUCCESS ) | |
f9026f4e | 80 | p_board->pos.y = 0; |
a3f2380f | 81 | |
9111d07d | 82 | size = sizeof( p_board->rows ); |
409fb90a MS |
83 | if( !RegQueryValueEx( hkey, "Height", NULL, &type, |
84 | (LPBYTE) &p_board->rows, &size ) == ERROR_SUCCESS ) | |
a3f2380f JT |
85 | p_board->rows = BEGINNER_ROWS; |
86 | ||
9111d07d | 87 | size = sizeof( p_board->cols ); |
409fb90a MS |
88 | if( !RegQueryValueEx( hkey, "Width", NULL, &type, |
89 | (LPBYTE) &p_board->cols, &size ) == ERROR_SUCCESS ) | |
9a624916 VB |
90 | p_board->cols = BEGINNER_COLS; |
91 | ||
9111d07d | 92 | size = sizeof( p_board->mines ); |
409fb90a MS |
93 | if( !RegQueryValueEx( hkey, "Mines", NULL, &type, |
94 | (LPBYTE) &p_board->mines, &size ) == ERROR_SUCCESS ) | |
9111d07d | 95 | p_board->mines = BEGINNER_MINES; |
a3f2380f | 96 | |
9111d07d | 97 | size = sizeof( p_board->difficulty ); |
409fb90a MS |
98 | if( !RegQueryValueEx( hkey, "Difficulty", NULL, &type, |
99 | (LPBYTE) &p_board->difficulty, &size ) == ERROR_SUCCESS ) | |
a3f2380f JT |
100 | p_board->difficulty = BEGINNER; |
101 | ||
9111d07d | 102 | size = sizeof( p_board->IsMarkQ ); |
409fb90a MS |
103 | if( !RegQueryValueEx( hkey, "Mark", NULL, &type, |
104 | (LPBYTE) &p_board->IsMarkQ, &size ) == ERROR_SUCCESS ) | |
a3f2380f | 105 | p_board->IsMarkQ = TRUE; |
9a624916 | 106 | |
a3f2380f | 107 | for( i = 0; i < 3; i++ ) { |
9111d07d | 108 | wsprintf( key_name, "Name%d", i+1 ); |
a3f2380f | 109 | size = sizeof( data ); |
409fb90a MS |
110 | if( RegQueryValueEx( hkey, key_name, NULL, &type, |
111 | (LPBYTE) data, &size ) == ERROR_SUCCESS ) | |
112 | lstrcpynA( p_board->best_name[i], data, sizeof(p_board->best_name[i]) ); | |
9a624916 | 113 | else |
b599f89a | 114 | LoadString( p_board->hInst, IDS_NOBODY, p_board->best_name[i], MAX_PLAYER_NAME_SIZE+1 ); |
a3f2380f | 115 | } |
9a624916 | 116 | |
a3f2380f | 117 | for( i = 0; i < 3; i++ ) { |
9111d07d JC |
118 | wsprintf( key_name, "Time%d", i+1 ); |
119 | size = sizeof( p_board->best_time[i] ); | |
409fb90a MS |
120 | if( !RegQueryValueEx( hkey, key_name, NULL, &type, |
121 | (LPBYTE) &p_board->best_time[i], &size ) == ERROR_SUCCESS ) | |
a3f2380f JT |
122 | p_board->best_time[i] = 999; |
123 | } | |
124 | RegCloseKey( hkey ); | |
125 | } | |
126 | ||
b82caec7 | 127 | static void InitBoard( BOARD *p_board ) |
a3f2380f | 128 | { |
eec04aeb | 129 | HMENU hMenu; |
9a624916 | 130 | |
eec04aeb FG |
131 | p_board->hMinesBMP = LoadBitmap( p_board->hInst, "mines"); |
132 | p_board->hFacesBMP = LoadBitmap( p_board->hInst, "faces"); | |
133 | p_board->hLedsBMP = LoadBitmap( p_board->hInst, "leds"); | |
134 | ||
135 | LoadBoard( p_board ); | |
136 | ||
137 | hMenu = GetMenu( p_board->hWnd ); | |
138 | CheckMenuItem( hMenu, IDM_BEGINNER + (unsigned) p_board->difficulty, | |
139 | MF_CHECKED ); | |
140 | if( p_board->IsMarkQ ) | |
141 | CheckMenuItem( hMenu, IDM_MARKQ, MF_CHECKED ); | |
142 | else | |
143 | CheckMenuItem( hMenu, IDM_MARKQ, MF_UNCHECKED ); | |
144 | CheckLevel( p_board ); | |
145 | } | |
146 | ||
b82caec7 | 147 | static void SaveBoard( BOARD *p_board ) |
eec04aeb FG |
148 | { |
149 | HKEY hkey; | |
150 | unsigned i; | |
151 | char data[MAX_PLAYER_NAME_SIZE+1]; | |
152 | char key_name[8]; | |
153 | ||
154 | if( RegCreateKeyEx( HKEY_CURRENT_USER, registry_key, | |
155 | 0, NULL, | |
156 | REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, | |
157 | &hkey, NULL ) != ERROR_SUCCESS) | |
158 | return; | |
9377ea99 | 159 | |
9111d07d JC |
160 | RegSetValueEx( hkey, "Xpos", 0, REG_DWORD, (LPBYTE) &p_board->pos.x, sizeof(p_board->pos.x) ); |
161 | RegSetValueEx( hkey, "Ypos", 0, REG_DWORD, (LPBYTE) &p_board->pos.y, sizeof(p_board->pos.y) ); | |
162 | RegSetValueEx( hkey, "Difficulty", 0, REG_DWORD, (LPBYTE) &p_board->difficulty, sizeof(p_board->difficulty) ); | |
163 | RegSetValueEx( hkey, "Height", 0, REG_DWORD, (LPBYTE) &p_board->rows, sizeof(p_board->rows) ); | |
164 | RegSetValueEx( hkey, "Width", 0, REG_DWORD, (LPBYTE) &p_board->cols, sizeof(p_board->cols) ); | |
165 | RegSetValueEx( hkey, "Mines", 0, REG_DWORD, (LPBYTE) &p_board->mines, sizeof(p_board->mines) ); | |
166 | RegSetValueEx( hkey, "Mark", 0, REG_DWORD, (LPBYTE) &p_board->IsMarkQ, sizeof(p_board->IsMarkQ) ); | |
a3f2380f JT |
167 | |
168 | for( i = 0; i < 3; i++ ) { | |
9111d07d | 169 | wsprintf( key_name, "Name%u", i+1 ); |
e732fc02 | 170 | lstrcpyn( data, p_board->best_name[i], sizeof( data ) ); |
9377ea99 | 171 | RegSetValueEx( hkey, key_name, 0, REG_SZ, (LPBYTE) data, strlen(data)+1 ); |
a3f2380f JT |
172 | } |
173 | ||
174 | for( i = 0; i < 3; i++ ) { | |
9111d07d JC |
175 | wsprintf( key_name, "Time%u", i+1 ); |
176 | RegSetValueEx( hkey, key_name, 0, REG_DWORD, (LPBYTE) &p_board->best_time[i], sizeof(p_board->best_time[i]) ); | |
a3f2380f JT |
177 | } |
178 | RegCloseKey( hkey ); | |
179 | } | |
180 | ||
b82caec7 | 181 | static void DestroyBoard( BOARD *p_board ) |
0872f30a JT |
182 | { |
183 | DeleteObject( p_board->hFacesBMP ); | |
184 | DeleteObject( p_board->hLedsBMP ); | |
185 | DeleteObject( p_board->hMinesBMP ); | |
186 | } | |
187 | ||
b82caec7 | 188 | static void SetDifficulty( BOARD *p_board, DIFFICULTY difficulty ) |
a3f2380f | 189 | { |
50a4503c PR |
190 | HMENU hMenu; |
191 | ||
192 | if ( difficulty == CUSTOM ) | |
193 | if (DialogBoxParam( p_board->hInst, "DLG_CUSTOM", p_board->hWnd, | |
194 | CustomDlgProc, (LPARAM) p_board) != 0) | |
195 | return; | |
a3f2380f | 196 | |
50a4503c | 197 | hMenu = GetMenu( p_board->hWnd ); |
a3f2380f | 198 | CheckMenuItem( hMenu, IDM_BEGINNER + p_board->difficulty, MF_UNCHECKED ); |
9a624916 | 199 | p_board->difficulty = difficulty; |
a3f2380f | 200 | CheckMenuItem( hMenu, IDM_BEGINNER + difficulty, MF_CHECKED ); |
9a624916 | 201 | |
a3f2380f | 202 | switch( difficulty ) { |
9a624916 | 203 | case BEGINNER: |
a3f2380f JT |
204 | p_board->cols = BEGINNER_COLS; |
205 | p_board->rows = BEGINNER_ROWS; | |
206 | p_board->mines = BEGINNER_MINES; | |
207 | break; | |
208 | ||
9a624916 | 209 | case ADVANCED: |
a3f2380f JT |
210 | p_board->cols = ADVANCED_COLS; |
211 | p_board->rows = ADVANCED_ROWS; | |
212 | p_board->mines = ADVANCED_MINES; | |
213 | break; | |
214 | ||
215 | case EXPERT: | |
216 | p_board->cols = EXPERT_COLS; | |
217 | p_board->rows = EXPERT_ROWS; | |
f9026f4e | 218 | |
9a624916 VB |
219 | p_board->mines = EXPERT_MINES; |
220 | break; | |
a3f2380f JT |
221 | |
222 | case CUSTOM: | |
9a624916 | 223 | break; |
a3f2380f JT |
224 | } |
225 | } | |
226 | ||
ae51135e | 227 | static void ShiftBetween(LONG* x, LONG* y, LONG a, LONG b) |
f9026f4e RC |
228 | { |
229 | if (*x < a) { | |
230 | *y += a - *x; | |
231 | *x = a; | |
232 | } | |
233 | else if (*y > b) { | |
234 | *x -= *y - b; | |
235 | *y = b; | |
236 | } | |
237 | } | |
ae51135e MM |
238 | |
239 | static void MoveOnScreen(RECT* rect) | |
f9026f4e RC |
240 | { |
241 | HMONITOR hMonitor; | |
242 | MONITORINFO mi; | |
243 | ||
244 | /* find the nearest monitor ... */ | |
245 | hMonitor = MonitorFromRect(rect, MONITOR_DEFAULTTONEAREST); | |
246 | ||
247 | /* ... and move it into the work area (ie excluding task bar)*/ | |
248 | mi.cbSize = sizeof(mi); | |
249 | GetMonitorInfo(hMonitor, &mi); | |
250 | ||
251 | ShiftBetween(&rect->left, &rect->right, mi.rcWork.left, mi.rcWork.right); | |
252 | ShiftBetween(&rect->top, &rect->bottom, mi.rcWork.top, mi.rcWork.bottom); | |
253 | } | |
254 | ||
b82caec7 | 255 | static void CreateBoard( BOARD *p_board ) |
a3f2380f | 256 | { |
f9026f4e | 257 | int left, top, bottom, right; |
04f925e7 | 258 | unsigned col, row; |
f9026f4e | 259 | RECT wnd_rect; |
a3f2380f JT |
260 | |
261 | p_board->mb = MB_NONE; | |
262 | p_board->boxes_left = p_board->cols * p_board->rows - p_board->mines; | |
263 | p_board->num_flags = 0; | |
9a624916 | 264 | |
04f925e7 DS |
265 | /* Create the boxes... |
266 | * We actually create them with an empty border, | |
267 | * so special care doesn't have to be taken on the edges | |
268 | */ | |
269 | for( col = 0; col <= p_board->cols + 1; col++ ) | |
270 | for( row = 0; row <= p_board->rows + 1; row++ ) { | |
271 | p_board->box[col][row].IsPressed = FALSE; | |
272 | p_board->box[col][row].IsMine = FALSE; | |
273 | p_board->box[col][row].FlagType = NORMAL; | |
274 | p_board->box[col][row].NumMines = 0; | |
275 | } | |
a3f2380f JT |
276 | |
277 | p_board->width = p_board->cols * MINE_WIDTH + BOARD_WMARGIN * 2; | |
9a624916 VB |
278 | |
279 | p_board->height = p_board->rows * MINE_HEIGHT + LED_HEIGHT | |
a3f2380f JT |
280 | + BOARD_HMARGIN * 3; |
281 | ||
9a624916 VB |
282 | /* setting the mines rectangle boundary */ |
283 | left = BOARD_WMARGIN; | |
284 | top = BOARD_HMARGIN * 2 + LED_HEIGHT; | |
a3f2380f JT |
285 | right = left + p_board->cols * MINE_WIDTH; |
286 | bottom = top + p_board->rows * MINE_HEIGHT; | |
287 | SetRect( &p_board->mines_rect, left, top, right, bottom ); | |
288 | ||
9a624916 | 289 | /* setting the face rectangle boundary */ |
a3f2380f JT |
290 | left = p_board->width / 2 - FACE_WIDTH / 2; |
291 | top = BOARD_HMARGIN; | |
292 | right = left + FACE_WIDTH; | |
9a624916 | 293 | bottom = top + FACE_HEIGHT; |
a3f2380f | 294 | SetRect( &p_board->face_rect, left, top, right, bottom ); |
9a624916 VB |
295 | |
296 | /* setting the timer rectangle boundary */ | |
a3f2380f JT |
297 | left = BOARD_WMARGIN; |
298 | top = BOARD_HMARGIN; | |
299 | right = left + LED_WIDTH * 3; | |
9a624916 | 300 | bottom = top + LED_HEIGHT; |
a3f2380f | 301 | SetRect( &p_board->timer_rect, left, top, right, bottom ); |
9a624916 VB |
302 | |
303 | /* setting the counter rectangle boundary */ | |
a3f2380f JT |
304 | left = p_board->width - BOARD_WMARGIN - LED_WIDTH * 3; |
305 | top = BOARD_HMARGIN; | |
306 | right = p_board->width - BOARD_WMARGIN; | |
9a624916 | 307 | bottom = top + LED_HEIGHT; |
a3f2380f | 308 | SetRect( &p_board->counter_rect, left, top, right, bottom ); |
9a624916 | 309 | |
a3f2380f | 310 | p_board->status = WAITING; |
9a624916 | 311 | p_board->face_bmp = SMILE_BMP; |
a3f2380f JT |
312 | p_board->time = 0; |
313 | ||
f9026f4e RC |
314 | wnd_rect.left = p_board->pos.x; |
315 | wnd_rect.right = p_board->pos.x + p_board->width; | |
316 | wnd_rect.top = p_board->pos.y; | |
317 | wnd_rect.bottom = p_board->pos.y + p_board->height; | |
318 | AdjustWindowRect(&wnd_rect, wnd_style, TRUE); | |
319 | ||
320 | /* Make sure the window is completely on the screen */ | |
321 | MoveOnScreen(&wnd_rect); | |
322 | MoveWindow( p_board->hWnd, wnd_rect.left, wnd_rect.top, | |
323 | wnd_rect.right - wnd_rect.left, | |
324 | wnd_rect.bottom - wnd_rect.top, | |
325 | TRUE ); | |
326 | RedrawWindow( p_board->hWnd, NULL, 0, | |
327 | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE); | |
a3f2380f JT |
328 | } |
329 | ||
330 | ||
04f925e7 | 331 | /* Randomly places mines everywhere except the selected box. */ |
b82caec7 | 332 | static void PlaceMines ( BOARD *p_board, int selected_col, int selected_row ) |
a3f2380f JT |
333 | { |
334 | int i, j; | |
335 | unsigned col, row; | |
336 | ||
337 | srand( (unsigned) time( NULL ) ); | |
338 | ||
04f925e7 DS |
339 | /* Temporarily place a mine at the selected box until all the other |
340 | * mines are placed, this avoids checking in the mine creation loop. */ | |
341 | p_board->box[selected_col][selected_row].IsMine = TRUE; | |
a3f2380f JT |
342 | |
343 | /* create mines */ | |
344 | i = 0; | |
f9026f4e RC |
345 | while( (unsigned) i < p_board->mines ) { |
346 | col = (int) (p_board->cols * (float) rand() / RAND_MAX + 1); | |
347 | row = (int) (p_board->rows * (float) rand() / RAND_MAX + 1); | |
a3f2380f JT |
348 | |
349 | if( !p_board->box[col][row].IsMine ) { | |
350 | i++; | |
351 | p_board->box[col][row].IsMine = TRUE; | |
352 | } | |
353 | } | |
354 | ||
04f925e7 DS |
355 | /* Remove temporarily placed mine for selected box */ |
356 | p_board->box[selected_col][selected_row].IsMine = FALSE; | |
357 | ||
a3f2380f JT |
358 | /* |
359 | * Now we label the remaining boxes with the | |
360 | * number of mines surrounding them. | |
361 | */ | |
a3f2380f JT |
362 | for( col = 1; col < p_board->cols + 1; col++ ) |
363 | for( row = 1; row < p_board->rows + 1; row++ ) { | |
364 | for( i = -1; i <= 1; i++ ) | |
365 | for( j = -1; j <= 1; j++ ) { | |
366 | if( p_board->box[col + i][row + j].IsMine ) { | |
367 | p_board->box[col][row].NumMines++ ; | |
368 | } | |
369 | } | |
370 | } | |
371 | } | |
372 | ||
b82caec7 | 373 | static void DrawMine( HDC hdc, HDC hMemDC, BOARD *p_board, unsigned col, unsigned row, BOOL IsPressed ) |
a3f2380f | 374 | { |
a3f2380f JT |
375 | MINEBMP_OFFSET offset = BOX_BMP; |
376 | ||
a3f2380f | 377 | if( col == 0 || col > p_board->cols || row == 0 || row > p_board->rows ) |
9a624916 | 378 | return; |
a3f2380f JT |
379 | |
380 | if( p_board->status == GAMEOVER ) { | |
381 | if( p_board->box[col][row].IsMine ) { | |
382 | switch( p_board->box[col][row].FlagType ) { | |
383 | case FLAG: | |
384 | offset = FLAG_BMP; | |
385 | break; | |
386 | case COMPLETE: | |
9a624916 | 387 | offset = EXPLODE_BMP; |
a3f2380f | 388 | break; |
5c4caa66 JT |
389 | case QUESTION: |
390 | /* fall through */ | |
a3f2380f JT |
391 | case NORMAL: |
392 | offset = MINE_BMP; | |
393 | } | |
9aaf13e7 | 394 | } else { |
9a624916 | 395 | switch( p_board->box[col][row].FlagType ) { |
a3f2380f | 396 | case QUESTION: |
9a624916 | 397 | offset = QUESTION_BMP; |
a3f2380f JT |
398 | break; |
399 | case FLAG: | |
400 | offset = WRONG_BMP; | |
401 | break; | |
9a624916 | 402 | case NORMAL: |
a3f2380f | 403 | offset = BOX_BMP; |
9aaf13e7 PH |
404 | break; |
405 | case COMPLETE: | |
406 | /* Do nothing */ | |
407 | break; | |
408 | default: | |
d38caa48 | 409 | WINE_TRACE("Unknown FlagType during game over in DrawMine\n"); |
9aaf13e7 | 410 | break; |
a3f2380f | 411 | } |
9a624916 | 412 | } |
9aaf13e7 | 413 | } else { /* WAITING or PLAYING */ |
a3f2380f JT |
414 | switch( p_board->box[col][row].FlagType ) { |
415 | case QUESTION: | |
9a624916 VB |
416 | if( !IsPressed ) |
417 | offset = QUESTION_BMP; | |
a3f2380f | 418 | else |
9a624916 | 419 | offset = QPRESS_BMP; |
a3f2380f JT |
420 | break; |
421 | case FLAG: | |
422 | offset = FLAG_BMP; | |
423 | break; | |
9a624916 | 424 | case NORMAL: |
a3f2380f JT |
425 | if( !IsPressed ) |
426 | offset = BOX_BMP; | |
9a624916 | 427 | else |
a3f2380f | 428 | offset = MPRESS_BMP; |
9aaf13e7 PH |
429 | break; |
430 | case COMPLETE: | |
431 | /* Do nothing */ | |
432 | break; | |
433 | default: | |
d38caa48 | 434 | WINE_TRACE("Unknown FlagType while playing in DrawMine\n"); |
9aaf13e7 | 435 | break; |
a3f2380f | 436 | } |
9a624916 | 437 | } |
a3f2380f | 438 | |
9a624916 | 439 | if( p_board->box[col][row].FlagType == COMPLETE |
9aaf13e7 | 440 | && !p_board->box[col][row].IsMine ) |
a3f2380f | 441 | offset = (MINEBMP_OFFSET) p_board->box[col][row].NumMines; |
9a624916 | 442 | |
a3f2380f | 443 | BitBlt( hdc, |
9aaf13e7 PH |
444 | (col - 1) * MINE_WIDTH + p_board->mines_rect.left, |
445 | (row - 1) * MINE_HEIGHT + p_board->mines_rect.top, | |
446 | MINE_WIDTH, MINE_HEIGHT, | |
447 | hMemDC, 0, offset * MINE_HEIGHT, SRCCOPY ); | |
a3f2380f JT |
448 | } |
449 | ||
b82caec7 | 450 | static void DrawMines ( HDC hdc, HDC hMemDC, BOARD *p_board ) |
eec04aeb FG |
451 | { |
452 | HGDIOBJ hOldObj; | |
453 | unsigned col, row; | |
454 | hOldObj = SelectObject (hMemDC, p_board->hMinesBMP); | |
455 | ||
456 | for( row = 1; row <= p_board->rows; row++ ) { | |
457 | for( col = 1; col <= p_board->cols; col++ ) { | |
458 | DrawMine( hdc, hMemDC, p_board, col, row, FALSE ); | |
459 | } | |
460 | } | |
461 | SelectObject( hMemDC, hOldObj ); | |
462 | } | |
463 | ||
b82caec7 | 464 | static void DrawLeds( HDC hdc, HDC hMemDC, BOARD *p_board, int number, int x, int y ) |
a3f2380f | 465 | { |
0872f30a | 466 | HGDIOBJ hOldObj; |
a3f2380f | 467 | unsigned led[3], i; |
9a624916 | 468 | int count; |
a3f2380f JT |
469 | |
470 | count = number; | |
471 | if( count < 1000 ) { | |
472 | if( count >= 0 ) { | |
473 | led[0] = count / 100 ; | |
474 | count -= led[0] * 100; | |
475 | } | |
476 | else { | |
477 | led[0] = 10; /* negative sign */ | |
478 | count = -count; | |
479 | } | |
480 | led[1] = count / 10; | |
481 | count -= led[1] * 10; | |
482 | led[2] = count; | |
483 | } | |
484 | else { | |
485 | for( i = 0; i < 3; i++ ) | |
486 | led[i] = 10; | |
487 | } | |
488 | ||
0872f30a | 489 | hOldObj = SelectObject (hMemDC, p_board->hLedsBMP); |
9aaf13e7 | 490 | |
a3f2380f JT |
491 | for( i = 0; i < 3; i++ ) { |
492 | BitBlt( hdc, | |
493 | i * LED_WIDTH + x, | |
494 | y, | |
495 | LED_WIDTH, | |
496 | LED_HEIGHT, | |
9a624916 VB |
497 | hMemDC, |
498 | 0, | |
499 | led[i] * LED_HEIGHT, | |
a3f2380f JT |
500 | SRCCOPY); |
501 | } | |
9a624916 | 502 | |
0872f30a | 503 | SelectObject( hMemDC, hOldObj ); |
a3f2380f JT |
504 | } |
505 | ||
506 | ||
b82caec7 | 507 | static void DrawFace( HDC hdc, HDC hMemDC, BOARD *p_board ) |
a3f2380f | 508 | { |
9a624916 | 509 | HGDIOBJ hOldObj; |
0872f30a JT |
510 | |
511 | hOldObj = SelectObject (hMemDC, p_board->hFacesBMP); | |
a3f2380f JT |
512 | |
513 | BitBlt( hdc, | |
514 | p_board->face_rect.left, | |
515 | p_board->face_rect.top, | |
516 | FACE_WIDTH, | |
517 | FACE_HEIGHT, | |
518 | hMemDC, 0, p_board->face_bmp * FACE_HEIGHT, SRCCOPY); | |
9a624916 | 519 | |
0872f30a | 520 | SelectObject( hMemDC, hOldObj ); |
a3f2380f JT |
521 | } |
522 | ||
523 | ||
b82caec7 | 524 | static void DrawBoard( HDC hdc, HDC hMemDC, PAINTSTRUCT *ps, BOARD *p_board ) |
a3f2380f | 525 | { |
9a624916 VB |
526 | RECT tmp_rect; |
527 | ||
528 | if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->counter_rect ) ) | |
9aaf13e7 PH |
529 | DrawLeds( hdc, hMemDC, p_board, p_board->mines - p_board->num_flags, |
530 | p_board->counter_rect.left, | |
531 | p_board->counter_rect.top ); | |
a3f2380f | 532 | |
9a624916 | 533 | if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->timer_rect ) ) |
9aaf13e7 | 534 | DrawLeds( hdc, hMemDC, p_board, p_board->time, |
9a624916 | 535 | p_board->timer_rect.left, |
9aaf13e7 | 536 | p_board->timer_rect.top ); |
9a624916 VB |
537 | |
538 | if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->face_rect ) ) | |
9aaf13e7 | 539 | DrawFace( hdc, hMemDC, p_board ); |
9a624916 VB |
540 | |
541 | if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->mines_rect ) ) | |
9aaf13e7 | 542 | DrawMines( hdc, hMemDC, p_board ); |
9a624916 | 543 | } |
a3f2380f JT |
544 | |
545 | ||
b82caec7 | 546 | static void AddFlag( BOARD *p_board, unsigned col, unsigned row ) |
a3f2380f | 547 | { |
eec04aeb FG |
548 | if( p_board->box[col][row].FlagType != COMPLETE ) { |
549 | switch( p_board->box[col][row].FlagType ) { | |
550 | case FLAG: | |
551 | if( p_board->IsMarkQ ) | |
552 | p_board->box[col][row].FlagType = QUESTION; | |
553 | else | |
554 | p_board->box[col][row].FlagType = NORMAL; | |
555 | p_board->num_flags--; | |
556 | break; | |
9a624916 | 557 | |
eec04aeb FG |
558 | case QUESTION: |
559 | p_board->box[col][row].FlagType = NORMAL; | |
560 | break; | |
a3f2380f | 561 | |
eec04aeb FG |
562 | default: |
563 | p_board->box[col][row].FlagType = FLAG; | |
564 | p_board->num_flags++; | |
565 | } | |
a3f2380f | 566 | } |
eec04aeb | 567 | } |
a3f2380f | 568 | |
9a624916 | 569 | |
b82caec7 | 570 | static void UnpressBox( BOARD *p_board, unsigned col, unsigned row ) |
eec04aeb FG |
571 | { |
572 | HDC hdc; | |
573 | HGDIOBJ hOldObj; | |
574 | HDC hMemDC; | |
dbcc37ba | 575 | |
eec04aeb FG |
576 | hdc = GetDC( p_board->hWnd ); |
577 | hMemDC = CreateCompatibleDC( hdc ); | |
578 | hOldObj = SelectObject( hMemDC, p_board->hMinesBMP ); | |
dbcc37ba | 579 | |
eec04aeb FG |
580 | DrawMine( hdc, hMemDC, p_board, col, row, FALSE ); |
581 | ||
582 | SelectObject( hMemDC, hOldObj ); | |
583 | DeleteDC( hMemDC ); | |
584 | ReleaseDC( p_board->hWnd, hdc ); | |
585 | } | |
586 | ||
587 | ||
b82caec7 | 588 | static void UnpressBoxes( BOARD *p_board, unsigned col, unsigned row ) |
eec04aeb FG |
589 | { |
590 | int i, j; | |
591 | ||
592 | for( i = -1; i <= 1; i++ ) | |
593 | for( j = -1; j <= 1; j++ ) { | |
594 | UnpressBox( p_board, col + i, row + j ); | |
595 | } | |
596 | } | |
597 | ||
598 | ||
b82caec7 | 599 | static void PressBox( BOARD *p_board, unsigned col, unsigned row ) |
eec04aeb FG |
600 | { |
601 | HDC hdc; | |
602 | HGDIOBJ hOldObj; | |
603 | HDC hMemDC; | |
604 | ||
605 | hdc = GetDC( p_board->hWnd ); | |
606 | hMemDC = CreateCompatibleDC( hdc ); | |
607 | hOldObj = SelectObject (hMemDC, p_board->hMinesBMP); | |
608 | ||
609 | DrawMine( hdc, hMemDC, p_board, col, row, TRUE ); | |
610 | ||
611 | SelectObject( hMemDC, hOldObj ); | |
612 | DeleteDC( hMemDC ); | |
613 | ReleaseDC( p_board->hWnd, hdc ); | |
614 | } | |
615 | ||
616 | ||
b82caec7 | 617 | static void PressBoxes( BOARD *p_board, unsigned col, unsigned row ) |
eec04aeb FG |
618 | { |
619 | int i, j; | |
620 | ||
621 | for( i = -1; i <= 1; i++ ) | |
622 | for( j = -1; j <= 1; j++ ) { | |
623 | p_board->box[col + i][row + j].IsPressed = TRUE; | |
624 | PressBox( p_board, col + i, row + j ); | |
625 | } | |
626 | ||
627 | for( i = -1; i <= 1; i++ ) | |
628 | for( j = -1; j <= 1; j++ ) { | |
629 | if( !p_board->box[p_board->press.x + i][p_board->press.y + j].IsPressed ) | |
630 | UnpressBox( p_board, p_board->press.x + i, p_board->press.y + j ); | |
631 | } | |
632 | ||
633 | for( i = -1; i <= 1; i++ ) | |
634 | for( j = -1; j <= 1; j++ ) { | |
635 | p_board->box[col + i][row + j].IsPressed = FALSE; | |
636 | PressBox( p_board, col + i, row + j ); | |
637 | } | |
638 | ||
639 | p_board->press.x = col; | |
640 | p_board->press.y = row; | |
641 | } | |
642 | ||
643 | ||
b82caec7 | 644 | static void CompleteBox( BOARD *p_board, unsigned col, unsigned row ) |
eec04aeb FG |
645 | { |
646 | int i, j; | |
647 | ||
648 | if( p_board->box[col][row].FlagType != COMPLETE && | |
649 | p_board->box[col][row].FlagType != FLAG && | |
650 | col > 0 && col < p_board->cols + 1 && | |
651 | row > 0 && row < p_board->rows + 1 ) { | |
652 | p_board->box[col][row].FlagType = COMPLETE; | |
653 | ||
654 | if( p_board->box[col][row].IsMine ) { | |
655 | p_board->face_bmp = DEAD_BMP; | |
656 | p_board->status = GAMEOVER; | |
dbcc37ba | 657 | } |
eec04aeb FG |
658 | else if( p_board->status != GAMEOVER ) |
659 | p_board->boxes_left--; | |
dbcc37ba | 660 | |
eec04aeb FG |
661 | if( p_board->box[col][row].NumMines == 0 ) |
662 | { | |
663 | for( i = -1; i <= 1; i++ ) | |
664 | for( j = -1; j <= 1; j++ ) | |
665 | CompleteBox( p_board, col + i, row + j ); | |
666 | } | |
667 | } | |
668 | } | |
9a624916 | 669 | |
9a624916 | 670 | |
b82caec7 | 671 | static void CompleteBoxes( BOARD *p_board, unsigned col, unsigned row ) |
eec04aeb FG |
672 | { |
673 | unsigned numFlags = 0; | |
674 | int i, j; | |
675 | ||
676 | if( p_board->box[col][row].FlagType == COMPLETE ) { | |
677 | for( i = -1; i <= 1; i++ ) | |
678 | for( j = -1; j <= 1; j++ ) { | |
679 | if( p_board->box[col+i][row+j].FlagType == FLAG ) | |
680 | numFlags++; | |
681 | } | |
682 | ||
683 | if( numFlags == p_board->box[col][row].NumMines ) { | |
684 | for( i = -1; i <= 1; i++ ) | |
685 | for( j = -1; j <= 1; j++ ) { | |
686 | if( p_board->box[col+i][row+j].FlagType != FLAG ) | |
687 | CompleteBox( p_board, col+i, row+j ); | |
688 | } | |
a3f2380f JT |
689 | } |
690 | } | |
a3f2380f JT |
691 | } |
692 | ||
eec04aeb | 693 | |
b82caec7 | 694 | static void TestMines( BOARD *p_board, POINT pt, int msg ) |
a3f2380f JT |
695 | { |
696 | BOOL draw = TRUE; | |
719a7897 | 697 | int col, row; |
a3f2380f JT |
698 | |
699 | col = (pt.x - p_board->mines_rect.left) / MINE_WIDTH + 1; | |
700 | row = (pt.y - p_board->mines_rect.top ) / MINE_HEIGHT + 1; | |
9a624916 | 701 | |
a3f2380f JT |
702 | switch ( msg ) { |
703 | case WM_LBUTTONDOWN: | |
704 | if( p_board->press.x != col || p_board->press.y != row ) { | |
9a624916 | 705 | UnpressBox( p_board, |
a3f2380f JT |
706 | p_board->press.x, p_board->press.y ); |
707 | p_board->press.x = col; | |
708 | p_board->press.y = row; | |
9a624916 VB |
709 | PressBox( p_board, col, row ); |
710 | } | |
711 | draw = FALSE; | |
a3f2380f JT |
712 | break; |
713 | ||
714 | case WM_LBUTTONUP: | |
715 | if( p_board->press.x != col || p_board->press.y != row ) | |
9a624916 | 716 | UnpressBox( p_board, |
a3f2380f JT |
717 | p_board->press.x, p_board->press.y ); |
718 | p_board->press.x = 0; | |
719 | p_board->press.y = 0; | |
04f925e7 DS |
720 | if( p_board->box[col][row].FlagType != FLAG |
721 | && p_board->status != PLAYING ) | |
722 | { | |
9a624916 | 723 | p_board->status = PLAYING; |
04f925e7 DS |
724 | PlaceMines( p_board, col, row ); |
725 | } | |
a3f2380f JT |
726 | CompleteBox( p_board, col, row ); |
727 | break; | |
728 | ||
729 | case WM_MBUTTONDOWN: | |
730 | PressBoxes( p_board, col, row ); | |
9aaf13e7 | 731 | draw = FALSE; |
a3f2380f JT |
732 | break; |
733 | ||
734 | case WM_MBUTTONUP: | |
735 | if( p_board->press.x != col || p_board->press.y != row ) | |
9a624916 | 736 | UnpressBoxes( p_board, |
a3f2380f JT |
737 | p_board->press.x, p_board->press.y ); |
738 | p_board->press.x = 0; | |
739 | p_board->press.y = 0; | |
740 | CompleteBoxes( p_board, col, row ); | |
741 | break; | |
742 | ||
743 | case WM_RBUTTONDOWN: | |
744 | AddFlag( p_board, col, row ); | |
9aaf13e7 PH |
745 | break; |
746 | default: | |
d38caa48 | 747 | WINE_TRACE("Unknown message type received in TestMines\n"); |
a3f2380f JT |
748 | break; |
749 | } | |
9aaf13e7 | 750 | |
a3f2380f JT |
751 | if( draw ) |
752 | { | |
f9026f4e | 753 | RedrawWindow( p_board->hWnd, NULL, 0, |
a3f2380f JT |
754 | RDW_INVALIDATE | RDW_UPDATENOW ); |
755 | } | |
9a624916 | 756 | } |
a3f2380f JT |
757 | |
758 | ||
b82caec7 | 759 | static void TestFace( BOARD *p_board, POINT pt, int msg ) |
a3f2380f JT |
760 | { |
761 | if( p_board->status == PLAYING || p_board->status == WAITING ) { | |
762 | if( msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN ) | |
763 | p_board->face_bmp = OOH_BMP; | |
764 | else p_board->face_bmp = SMILE_BMP; | |
765 | } | |
9a624916 | 766 | else if( p_board->status == GAMEOVER ) |
a3f2380f | 767 | p_board->face_bmp = DEAD_BMP; |
9a624916 | 768 | else if( p_board->status == WON ) |
a3f2380f JT |
769 | p_board->face_bmp = COOL_BMP; |
770 | ||
9a624916 VB |
771 | if( PtInRect( &p_board->face_rect, pt ) ) { |
772 | if( msg == WM_LBUTTONDOWN ) | |
a3f2380f | 773 | p_board->face_bmp = SPRESS_BMP; |
9a624916 VB |
774 | |
775 | if( msg == WM_LBUTTONUP ) | |
776 | CreateBoard( p_board ); | |
a3f2380f | 777 | } |
9aaf13e7 | 778 | |
f9026f4e | 779 | RedrawWindow( p_board->hWnd, &p_board->face_rect, 0, |
a3f2380f JT |
780 | RDW_INVALIDATE | RDW_UPDATENOW ); |
781 | } | |
782 | ||
783 | ||
b82caec7 | 784 | static void TestBoard( HWND hWnd, BOARD *p_board, int x, int y, int msg ) |
a3f2380f | 785 | { |
eec04aeb FG |
786 | POINT pt; |
787 | unsigned col,row; | |
a3f2380f | 788 | |
eec04aeb FG |
789 | pt.x = x; |
790 | pt.y = y; | |
9a624916 | 791 | |
eec04aeb FG |
792 | if( PtInRect( &p_board->mines_rect, pt ) && p_board->status != GAMEOVER |
793 | && p_board->status != WON ) | |
794 | TestMines( p_board, pt, msg ); | |
795 | else { | |
796 | UnpressBoxes( p_board, | |
797 | p_board->press.x, | |
798 | p_board->press.y ); | |
799 | p_board->press.x = 0; | |
800 | p_board->press.y = 0; | |
9a624916 | 801 | } |
a3f2380f | 802 | |
eec04aeb FG |
803 | if( p_board->boxes_left == 0 ) { |
804 | p_board->status = WON; | |
a3f2380f | 805 | |
eec04aeb FG |
806 | if (p_board->num_flags < p_board->mines) { |
807 | for( row = 1; row <= p_board->rows; row++ ) { | |
808 | for( col = 1; col <= p_board->cols; col++ ) { | |
809 | if (p_board->box[col][row].IsMine && p_board->box[col][row].FlagType != FLAG) | |
810 | p_board->box[col][row].FlagType = FLAG; | |
811 | } | |
812 | } | |
a3f2380f | 813 | |
eec04aeb | 814 | p_board->num_flags = p_board->mines; |
9a624916 | 815 | |
eec04aeb FG |
816 | RedrawWindow( p_board->hWnd, NULL, 0, |
817 | RDW_INVALIDATE | RDW_UPDATENOW ); | |
a3f2380f | 818 | } |
a3f2380f | 819 | |
eec04aeb FG |
820 | if( p_board->difficulty != CUSTOM && |
821 | p_board->time < p_board->best_time[p_board->difficulty] ) { | |
822 | p_board->best_time[p_board->difficulty] = p_board->time; | |
a3f2380f | 823 | |
eec04aeb FG |
824 | DialogBoxParam( p_board->hInst, "DLG_CONGRATS", hWnd, |
825 | CongratsDlgProc, (LPARAM) p_board); | |
9a624916 | 826 | |
eec04aeb FG |
827 | DialogBoxParam( p_board->hInst, "DLG_TIMES", hWnd, |
828 | TimesDlgProc, (LPARAM) p_board); | |
9a624916 VB |
829 | } |
830 | } | |
eec04aeb | 831 | TestFace( p_board, pt, msg ); |
a3f2380f JT |
832 | } |
833 | ||
834 | ||
b82caec7 | 835 | static LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
a3f2380f | 836 | { |
9a624916 | 837 | HDC hdc; |
eec04aeb FG |
838 | PAINTSTRUCT ps; |
839 | HMENU hMenu; | |
840 | static BOARD board; | |
a3f2380f | 841 | |
eec04aeb FG |
842 | switch( msg ) { |
843 | case WM_CREATE: | |
844 | board.hInst = ((LPCREATESTRUCT) lParam)->hInstance; | |
845 | board.hWnd = hWnd; | |
846 | InitBoard( &board ); | |
847 | CreateBoard( &board ); | |
848 | return 0; | |
9aaf13e7 | 849 | |
eec04aeb FG |
850 | case WM_PAINT: |
851 | { | |
852 | HDC hMemDC; | |
9aaf13e7 | 853 | |
eec04aeb FG |
854 | WINE_TRACE("WM_PAINT\n"); |
855 | hdc = BeginPaint( hWnd, &ps ); | |
856 | hMemDC = CreateCompatibleDC( hdc ); | |
a3f2380f | 857 | |
eec04aeb | 858 | DrawBoard( hdc, hMemDC, &ps, &board ); |
a3f2380f | 859 | |
eec04aeb FG |
860 | DeleteDC( hMemDC ); |
861 | EndPaint( hWnd, &ps ); | |
a3f2380f | 862 | |
eec04aeb FG |
863 | return 0; |
864 | } | |
a3f2380f | 865 | |
eec04aeb FG |
866 | case WM_MOVE: |
867 | WINE_TRACE("WM_MOVE\n"); | |
868 | board.pos.x = (short)LOWORD(lParam); | |
869 | board.pos.y = (short)HIWORD(lParam); | |
870 | return 0; | |
a3f2380f | 871 | |
eec04aeb FG |
872 | case WM_DESTROY: |
873 | SaveBoard( &board ); | |
874 | DestroyBoard( &board ); | |
875 | PostQuitMessage( 0 ); | |
876 | return 0; | |
877 | ||
878 | case WM_TIMER: | |
879 | if( board.status == PLAYING ) { | |
880 | board.time++; | |
881 | RedrawWindow( hWnd, &board.timer_rect, 0, | |
882 | RDW_INVALIDATE | RDW_UPDATENOW ); | |
883 | } | |
884 | return 0; | |
885 | ||
886 | case WM_LBUTTONDOWN: | |
887 | WINE_TRACE("WM_LBUTTONDOWN\n"); | |
888 | if( wParam & MK_RBUTTON ) | |
889 | msg = WM_MBUTTONDOWN; | |
890 | TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg ); | |
891 | SetCapture( hWnd ); | |
892 | return 0; | |
893 | ||
894 | case WM_LBUTTONUP: | |
895 | WINE_TRACE("WM_LBUTTONUP\n"); | |
896 | if( wParam & MK_RBUTTON ) | |
897 | msg = WM_MBUTTONUP; | |
898 | TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg ); | |
899 | ReleaseCapture(); | |
900 | return 0; | |
901 | ||
902 | case WM_RBUTTONDOWN: | |
903 | WINE_TRACE("WM_RBUTTONDOWN\n"); | |
904 | if( wParam & MK_LBUTTON ) { | |
905 | board.press.x = 0; | |
906 | board.press.y = 0; | |
907 | msg = WM_MBUTTONDOWN; | |
908 | } | |
909 | TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg ); | |
910 | return 0; | |
911 | ||
912 | case WM_RBUTTONUP: | |
913 | WINE_TRACE("WM_RBUTTONUP\n"); | |
914 | if( wParam & MK_LBUTTON ) | |
915 | msg = WM_MBUTTONUP; | |
916 | TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg ); | |
917 | return 0; | |
918 | ||
919 | case WM_MBUTTONDOWN: | |
920 | WINE_TRACE("WM_MBUTTONDOWN\n"); | |
921 | TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg ); | |
922 | return 0; | |
923 | ||
924 | case WM_MBUTTONUP: | |
925 | WINE_TRACE("WM_MBUTTONUP\n"); | |
926 | TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg ); | |
927 | return 0; | |
928 | ||
929 | case WM_MOUSEMOVE: | |
930 | { | |
56a57f0c AL |
931 | if( ( wParam & MK_MBUTTON ) || |
932 | ( ( wParam & MK_LBUTTON ) && ( wParam & MK_RBUTTON ) ) ) { | |
eec04aeb FG |
933 | msg = WM_MBUTTONDOWN; |
934 | } | |
935 | else if( wParam & MK_LBUTTON ) { | |
936 | msg = WM_LBUTTONDOWN; | |
937 | } | |
938 | else { | |
939 | return 0; | |
940 | } | |
941 | ||
942 | TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg ); | |
943 | ||
944 | return 0; | |
a3f2380f JT |
945 | } |
946 | ||
eec04aeb FG |
947 | case WM_COMMAND: |
948 | switch(LOWORD(wParam)) { | |
949 | case IDM_NEW: | |
950 | CreateBoard( &board ); | |
951 | return 0; | |
a3f2380f | 952 | |
eec04aeb FG |
953 | case IDM_MARKQ: |
954 | hMenu = GetMenu( hWnd ); | |
955 | board.IsMarkQ = !board.IsMarkQ; | |
956 | if( board.IsMarkQ ) | |
957 | CheckMenuItem( hMenu, IDM_MARKQ, MF_CHECKED ); | |
958 | else | |
959 | CheckMenuItem( hMenu, IDM_MARKQ, MF_UNCHECKED ); | |
960 | return 0; | |
a3f2380f | 961 | |
eec04aeb FG |
962 | case IDM_BEGINNER: |
963 | SetDifficulty( &board, BEGINNER ); | |
964 | CreateBoard( &board ); | |
965 | return 0; | |
a3f2380f | 966 | |
eec04aeb FG |
967 | case IDM_ADVANCED: |
968 | SetDifficulty( &board, ADVANCED ); | |
969 | CreateBoard( &board ); | |
970 | return 0; | |
9aaf13e7 | 971 | |
eec04aeb FG |
972 | case IDM_EXPERT: |
973 | SetDifficulty( &board, EXPERT ); | |
974 | CreateBoard( &board ); | |
975 | return 0; | |
9aaf13e7 | 976 | |
eec04aeb FG |
977 | case IDM_CUSTOM: |
978 | SetDifficulty( &board, CUSTOM ); | |
979 | CreateBoard( &board ); | |
980 | return 0; | |
981 | ||
982 | case IDM_EXIT: | |
983 | SendMessage( hWnd, WM_CLOSE, 0, 0); | |
984 | return 0; | |
a3f2380f | 985 | |
eec04aeb FG |
986 | case IDM_TIMES: |
987 | DialogBoxParam( board.hInst, "DLG_TIMES", hWnd, | |
988 | TimesDlgProc, (LPARAM) &board); | |
989 | return 0; | |
a3f2380f | 990 | |
eec04aeb FG |
991 | case IDM_ABOUT: |
992 | { | |
993 | WCHAR appname[256], other[256]; | |
994 | LoadStringW( board.hInst, IDS_APPNAME, appname, sizeof(appname)/sizeof(WCHAR) ); | |
995 | LoadStringW( board.hInst, IDS_ABOUT, other, sizeof(other)/sizeof(WCHAR) ); | |
996 | ShellAboutW( hWnd, appname, other, | |
997 | LoadImageA( board.hInst, "WINEMINE", IMAGE_ICON, 48, 48, LR_SHARED )); | |
998 | return 0; | |
999 | } | |
1000 | default: | |
1001 | WINE_TRACE("Unknown WM_COMMAND command message received\n"); | |
1002 | break; | |
1003 | } | |
1004 | } | |
1005 | return( DefWindowProc( hWnd, msg, wParam, lParam )); | |
1006 | } | |
1007 | ||
1008 | int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdline, int cmdshow ) | |
a3f2380f | 1009 | { |
eec04aeb | 1010 | MSG msg; |
09989010 | 1011 | WNDCLASSEX wc; |
eec04aeb FG |
1012 | HWND hWnd; |
1013 | HACCEL haccel; | |
1014 | char appname[20]; | |
9a624916 | 1015 | |
eec04aeb FG |
1016 | LoadString( hInst, IDS_APPNAME, appname, sizeof(appname)); |
1017 | ||
8a2cb8fe | 1018 | wc.cbSize = sizeof(wc); |
eec04aeb FG |
1019 | wc.style = 0; |
1020 | wc.lpfnWndProc = MainProc; | |
1021 | wc.cbClsExtra = 0; | |
1022 | wc.cbWndExtra = 0; | |
1023 | wc.hInstance = hInst; | |
1024 | wc.hIcon = LoadIcon( hInst, "WINEMINE" ); | |
1025 | wc.hCursor = LoadCursor( 0, IDI_APPLICATION ); | |
409fb90a | 1026 | wc.hbrBackground = GetStockObject( BLACK_BRUSH ); |
eec04aeb FG |
1027 | wc.lpszMenuName = "MENU_WINEMINE"; |
1028 | wc.lpszClassName = appname; | |
09989010 AJ |
1029 | wc.hIconSm = LoadImage( hInst, "WINEMINE", IMAGE_ICON, |
1030 | GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED ); | |
eec04aeb | 1031 | |
09989010 | 1032 | if (!RegisterClassEx(&wc)) ExitProcess(1); |
eec04aeb FG |
1033 | hWnd = CreateWindow( appname, appname, |
1034 | wnd_style, | |
1035 | CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, | |
1036 | 0, 0, hInst, NULL ); | |
1037 | ||
1038 | if (!hWnd) ExitProcess(1); | |
1039 | ||
1040 | ShowWindow( hWnd, cmdshow ); | |
1041 | UpdateWindow( hWnd ); | |
1042 | ||
1043 | haccel = LoadAccelerators( hInst, MAKEINTRESOURCE(IDA_WINEMINE) ); | |
1044 | SetTimer( hWnd, ID_TIMER, 1000, NULL ); | |
1045 | ||
1046 | while( GetMessage(&msg, 0, 0, 0) ) { | |
1047 | if (!TranslateAccelerator( hWnd, haccel, &msg )) | |
1048 | TranslateMessage( &msg ); | |
1049 | ||
1050 | DispatchMessage( &msg ); | |
1051 | } | |
1052 | return msg.wParam; | |
a3f2380f | 1053 | } |