comparison g23m/condat/ms/src/bmi/Mmigame.c @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:509db1a7b7b8
1 /*******************************************************************************
2
3 CONDAT (UK)
4
5 ********************************************************************************
6
7 This software product is the property of Condat (UK) Ltd and may not be
8 disclosed to any third party without the express permission of the owner.
9
10 ********************************************************************************
11
12 $Project name: Basic MMI
13 $Project code: BMI (6349)
14 $Module: Game
15 $File: Mmigame.c
16 $Revision: 1.0
17
18 $Author: Condat(UK)
19 $Date: 03/07/01
20
21 ********************************************************************************
22
23 Description
24 Aug 16, 2004 REF: CRR 24323 Deepa M.D
25 Bug:Clenup of sprintf used for tracing
26 Fix:Replace the char buf[]; sprintf (buf, "...", ...); TRACE_EVENT (buf); statements by TRACE_EVENT_PX
27
28 This provides the main game (four in a row) functionality
29
30
31 ********************************************************************************/
32
33
34 /*******************************************************************************
35
36 Include files
37
38 *******************************************************************************/
39
40 #define ENTITY_MFW
41
42 /* includes */
43 #include <string.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46
47 #if defined (NEW_FRAME)
48
49 #include "typedefs.h"
50 #include "vsi.h"
51 #include "pei.h"
52 #include "custom.h"
53 #include "gsm.h"
54
55 #else
56
57 #include "STDDEFS.H"
58 #include "custom.h"
59 #include "gsm.h"
60 #include "vsi.h"
61
62 #endif
63 #include "mfw_sys.h"
64
65 #include "cus_aci.h"
66
67 #include "mfw_mfw.h"
68 #include "mfw_win.h"
69 #include "mfw_kbd.h"
70 /* SPR#1428 - SH - New Editor changes */
71 #ifndef NEW_EDITOR
72 #include "mfw_edt.h"
73 #endif
74 #include "mfw_lng.h"
75 #include "mfw_tim.h"
76 #include "mfw_icn.h"
77 #include "mfw_mnu.h"
78 #include "mfw_phb.h"
79 #include "mfw_cm.h"
80 #include "mfw_sim.h"
81 #include "mfw_nm.h"
82 #include "mfw_sat.h"
83 #include "mfw_ss.h" /*for convert*/
84 #include "mfw_phb.h"
85 #include "ksd.h"
86 #include "psa.h"
87 #include "mfw_sms.h"
88 #include "mfw_cphs.h"
89 #include "mfw_sat.h"
90 #include "Mfw_band.h"
91 #include "mfw_ffs.h"
92 #include "Mmigame.h"
93
94 #include "dspl.h"
95
96 #include "MmiMmi.h"
97 #include "MmiDialogs.h"
98 #include "MmiLists.h"
99 #include "MmiBand.h"
100 #include "MmiCPHS.h"
101 /* SPR#1428 - SH - New Editor changes */
102 #ifdef NEW_EDITOR
103 #include "ATBCommon.h"
104 #include "ATBDisplay.h"
105 #include "ATBEditor.h"
106 #include "AUIEditor.h"
107 #else
108 #include "MmiEditor.h"
109 #endif
110 #include"MmiBookShared.h"
111
112
113
114
115 #include "font_bitmaps.h"
116 #include "mmiColours.h"
117 #include "MmiResources.h"
118
119 #include "Mmigame.h"
120 //GW 14/09/01 Disable game when not required.
121 #ifdef MMIGAME
122 void dspl_show_bitmap(int x,int y,t_font_bitmap* current_bitmap,U32 attr );
123 /*******************************************************************************
124
125 internal data
126
127 *******************************************************************************/
128
129 #define FOUR_IN_A_ROW_INIT 121
130 #define MAX_X_BOARD 11
131 #define MAX_Y_BOARD 8
132 /*
133 * The information related to every window must be encapsulated in such an structure
134 */
135
136 typedef struct
137 {
138 T_MMI_CONTROL mmi_control; // common control parameter
139 T_MFW_HND win;
140 T_MFW_HND kbd;
141 T_MFW_HND menu;
142 T_MFW_HND parent_win;
143 T_MFW_HND info_win;
144 char board_array[MAX_Y_BOARD][MAX_X_BOARD]; //the virtual board
145 } T_four_in_a_row;
146
147 typedef struct
148 {
149 /* administrative data */
150
151 T_MMI_CONTROL mmi_control;
152 T_MFW_HND win;
153 T_MFW_HND parent_win;
154 /* SPR#1428 - SH - New editor data */
155 #ifdef NEW_EDITOR
156 T_AUI_EDITOR_DATA editor_data;
157 #else /* NEW_EDITOR */
158 T_EDITOR_DATA editor_data;
159 #endif /* NEW_EDITOR */
160
161 /* internal data */
162 char buffer[80];
163 UBYTE status;
164
165 } tShowInfo;
166
167
168 /*
169 * These are common functions xxx_create and xxx_destroy
170 */
171 T_MFW_HND four_in_a_row_create(MfwHnd parent);
172 void four_in_a_row_destroy (T_MFW_HND);
173
174
175 /*
176 * This dialog function (the same name as the window)
177 * is used to handle the comunication between different windows. The global macro SEND_EVENT can be used with parameter win
178 * and the corresponding events to send from one mmi dialog to another.
179 */
180 void four_in_a_row (T_MFW_HND win, USHORT event, SHORT value, void * parameter);
181
182
183 /*
184 * These are common optional functions handler
185 */
186 int four_in_a_row_kbd_cb (MfwEvt e, MfwKbd *k);
187 int four_in_a_row_win_cb (MfwEvt e, MfwWin *w);
188
189 int Game_Result;
190
191
192 /*
193 * This an optional function, used often to call, create and init a new dialog, with different parameters depending
194 * on the context
195 */
196 T_MFW_HND four_in_a_row_start (T_MFW_HND win_parent,char *character);
197 int four_in_a_row_aktivate(MfwMnu* m, MfwMnuItem* i);
198
199 int check_column(T_four_in_a_row *data, int where_from);
200 void drop_stone(T_four_in_a_row *data);
201
202 int mobile_thinking(T_four_in_a_row *data);
203 int check_line(T_four_in_a_row *data, int x_value, int drop_position, int dx, int dy, BOOL where_from);
204 void check_for_winner(T_four_in_a_row *data, int check_out_position);
205 int random_scoring(void); // RAVI
206
207 T_MFW_HND Game_Info(T_MFW_HND parent_window);
208 static T_MFW_HND ShowGame_Information(MfwHnd parent_window);
209 static void ShowGame_DialogCB(T_MFW_HND win, USHORT e, SHORT identifier, void *parameter);
210 void ShowGameInfoEditor(T_MFW_HND win);
211 static void ShowInfoCB( T_MFW_HND win, USHORT Identifier,UBYTE reason);
212 void showGameInfo_destroy(MfwHnd own_window);
213
214 const char * info = "Welcome to Connect 4!";
215 const char * playAgain = "Play Again?";
216
217
218 //internal datas
219
220 int column; //this is the current position of white player cursor
221 int x_runer; //goes through the horizontal lines
222 int y_runer; //goes through the vertical lines
223 char winner; //describes the winner 0->nobody 'B'->black(mobile) 'W'->white(human player)
224 int column_black; //this is the current position of black player cursor
225 int request_stone; //helps to decide between black or white (for strategical things)
226
227 static T_MFW_HND info_window=0;
228
229 #ifndef BMP_FORMAT_BW_UNPACKED
230 #define BMP_FORMAT_BW_UNPACKED 1
231 #endif
232
233
234 t_font_bitmap plWin1 ={ 0, BMP_FORMAT_BW_UNPACKED, 21, 24, 0, (char*)player_win1};
235 t_font_bitmap plWin2 ={ 0, BMP_FORMAT_BW_UNPACKED, 21, 24, 0, (char*)player_win2};
236 t_font_bitmap plLost1 ={ 0, BMP_FORMAT_BW_UNPACKED, 21, 24, 0, (char*)player_lost1};
237 t_font_bitmap plLost2 ={ 0, BMP_FORMAT_BW_UNPACKED, 21, 24, 0, (char*)player_lost2};
238 t_font_bitmap draw1 ={ 0, BMP_FORMAT_BW_UNPACKED, 21, 24, 0, (char*)board_full1};
239 t_font_bitmap draw2 ={ 0, BMP_FORMAT_BW_UNPACKED, 21, 24, 0, (char*)board_full2};
240 t_font_bitmap gameName1 ={ 0, BMP_FORMAT_BW_UNPACKED, 18, 24, 0, (char*)game_name1};
241 t_font_bitmap gameName2 ={ 0, BMP_FORMAT_BW_UNPACKED, 24, 24, 0, (char*)game_name2};
242
243 #ifdef COLOURDISPLAY
244 char colBmp[256*4];
245 t_font_bitmap allCol ={ 0, BMP_FORMAT_256_COLOUR, 32, 32, 0, colBmp };
246 t_font_bitmap stone_colour ={ 0, BMP_FORMAT_BW_UNPACKED, 8, 8, 0, (char*)black_stone_bw};
247 t_font_bitmap gameCursor = { 0, BMP_FORMAT_BW_UNPACKED, 8, 8, 0, (char*)game_cursor};
248 #else
249 #ifdef LSCREEN
250 t_font_bitmap blackStone_bw ={ 0, BMP_FORMAT_BW_UNPACKED, 8, 8, 0, (char*)black_stone_bw};
251 t_font_bitmap whiteStone_bw ={ 0, BMP_FORMAT_BW_UNPACKED, 8, 8, 0, (char*)white_stone_bw};
252 t_font_bitmap gameCursor = { 0, BMP_FORMAT_BW_UNPACKED, 8, 8, 0, (char*)game_cursor};
253 #else
254 t_font_bitmap blackStone_bw ={ 0, BMP_FORMAT_BW_UNPACKED, 4, 4, 0, (char*)black_stone_bw};
255 t_font_bitmap whiteStone_bw ={ 0, BMP_FORMAT_BW_UNPACKED, 4, 4, 0, (char*)white_stone_bw};
256 t_font_bitmap gameCursor = { 0, BMP_FORMAT_BW_UNPACKED, 6, 6, 0, (char*)game_cursor};
257 #endif
258 #endif
259
260 t_font_bitmap *blackStone, *whiteStone;
261
262 /*******************************************************************************
263
264 $Function: four_in_a_row_create
265
266 $Description:
267
268 $Returns:
269
270 $Arguments:
271
272 *******************************************************************************/
273
274
275 T_MFW_HND four_in_a_row_create (T_MFW_HND parent_window)
276 {
277
278 T_MFW_WIN * win;
279
280 /*
281 * This window is dynamic, for that reason the associated data are allocated in the mfw heap
282 */
283 T_four_in_a_row * data = (T_four_in_a_row *)ALLOC_MEMORY (sizeof (T_four_in_a_row));
284
285 TRACE_FUNCTION ("four_in_a_row_create()");
286
287 /*
288 * Create window handler
289 */
290
291 data->win = win_create (parent_window, 0, E_WIN_VISIBLE, (T_MFW_CB)four_in_a_row_win_cb);
292
293 if (data->win EQ 0)
294 return 0;
295
296 /*
297 * These assignments are necessary to attach the data to the window, and to handle the mmi event communication.
298 */
299
300 data->mmi_control.dialog = (T_DIALOG_FUNC)four_in_a_row;
301 data->mmi_control.data = data;
302 data->parent_win = parent_window;
303 win = ((T_MFW_HDR *)data->win)->data;
304 win->user = (void *) data;
305
306 /*
307 * Create any other handler
308 */
309
310 data->kbd = kbd_create (data->win,KEY_ALL,(T_MFW_CB)four_in_a_row_kbd_cb);
311
312 column=0; //set start value for game cursor
313 winner ='0'; //game starts, so set winner to nobody
314
315 /*clear the board*/
316 for (y_runer=0;y_runer<MAX_Y_BOARD;y_runer++){
317 for(x_runer=0;x_runer<MAX_X_BOARD;x_runer++){
318 data->board_array[y_runer][x_runer] ='0';
319 }
320 }
321 winShow(data->win);
322
323 return data->win;
324 }
325
326 /*******************************************************************************
327
328 $Function: four_in_a_rowr_destroy
329
330 $Description:
331
332 $Returns:
333
334 $Arguments:
335
336 *******************************************************************************/
337
338 void four_in_a_row_destroy (T_MFW_HND own_window)
339 {
340 T_MFW_WIN * win;
341 T_four_in_a_row * data;
342
343 TRACE_EVENT("four_in_a_row_destroy");
344
345 if (own_window)
346 {
347 win = ((T_MFW_HDR *)own_window)->data;
348 data = (T_four_in_a_row *)win->user;
349
350 if (data)
351 {
352 /*
353 * Exit Keyboard Handler
354 */
355 /*
356 * Delete WIN Handler
357 */
358 win_delete (data->win);
359 }
360
361 /*
362 * In this case the data attached to window must be also deleted.
363 */
364 FREE_MEMORY ((void *)data, sizeof (T_four_in_a_row));
365
366 column=0; //set the current column back to 0
367
368 }
369 }
370
371 /*******************************************************************************
372
373 $Function: four_in_a_row_start
374
375 $Description: This function just creates and inits the new dialog
376
377 $Returns:
378
379 $Arguments:
380
381 *******************************************************************************/
382 T_MFW_HND four_in_a_row_start (T_MFW_HND win_parent,char *character)
383 {
384 T_MFW_HND win;
385 /*
386 MmiTetrisStart();
387 return;
388 */
389 win = four_in_a_row_create (win_parent);
390 TRACE_EVENT("four_in_a_row_start");
391
392 if (win NEQ NULL)
393 {
394 SEND_EVENT(win,FOUR_IN_A_ROW_INIT,0,character);
395 }
396 return win;
397
398 }
399
400 /*******************************************************************************
401
402 $Function: four_in_a_row
403
404 $Description:
405
406 $Returns:
407
408 $Arguments:
409
410 *******************************************************************************/
411
412
413
414 void four_in_a_row (T_MFW_HND win, USHORT event, SHORT value, void * parameter)
415 {
416 T_MFW_WIN * win_data = ((T_MFW_HDR *) win)->data;
417 T_four_in_a_row * data = (T_four_in_a_row *)win_data->user;
418
419 TRACE_FUNCTION ("four_in_a_row()");
420
421 /*
422 * In this case the communication is very simple (only one intern event)
423 */
424
425
426 switch (event)
427 {
428 case FOUR_IN_A_ROW_INIT:
429 softKeys_displayId(TxtSearchName,TxtNull,0,COLOUR_IDLE);
430 winShow(data->win);
431 break;
432
433 default:
434 return;
435 }
436
437 }
438
439 /*******************************************************************************
440
441 $Function: four_in_a_row_win_cb
442
443 $Description: win calback function of four in a row
444
445 $Returns:
446
447 $Arguments:
448
449 *******************************************************************************/
450
451
452 int four_in_a_row_win_cb (MfwEvt e, MfwWin *w)
453 {
454 // T_DISPLAY_DATA display_info; // RAVI
455 T_four_in_a_row * data = (T_four_in_a_row *)w->user;
456 int xOfs,yOfs, xScale, yScale;
457 int manOfsX,manOfsY;
458 int xPos,yPos;
459 int y_axis; //goes through the vertical lines
460 int x_axis; //goes through the horizontal lines
461 // int x,y,i,b; // RAVI
462 int displayPosX, temp;
463
464 TRACE_FUNCTION ("four_in_a_row_win_cb()");
465
466 switch (e)
467 {
468 case MfwWinVisible:
469 #ifdef COLOURDISPLAY
470 whiteStone = &stone_colour;
471 blackStone = &stone_colour;
472
473 #else
474 whiteStone = &blackStone_bw;
475 blackStone = &whiteStone_bw;
476
477 #endif
478 #ifdef LSCREEN
479 manOfsX = GAME_POS_X + 3;
480 manOfsY = GAME_POS_Y + 3;
481 #else
482 manOfsX = GAME_POS_X + 1;
483 manOfsY = GAME_POS_Y + 1;
484 #endif
485 xOfs = GAME_POS_X;
486 yOfs = GAME_POS_Y;
487 xScale = GAME_SCALE_X;
488 yScale = GAME_SCALE_Y;
489
490 //dspl_ClearAll(); //Clears to white, not BGD!
491 TRACE_EVENT("display clear");
492 resources_setColour( COLOUR_GAME );
493 dspl_Clear( 0,0, SCREEN_SIZE_X,SCREEN_SIZE_Y);
494 #ifdef LSCREEN
495 softKeys_displayId(TxtHelp,TxtExit,0,COLOUR_LIST_SUBMENU);
496 #endif
497
498 resources_setColour( COLOUR_GAME );
499 dspl_Clear( xOfs, yOfs, xOfs+MAX_X_BOARD*xScale, yOfs+MAX_Y_BOARD*yScale ); //Clears to white, not BGD!
500 //dspl_BitBlt(column*xScale+xOfs+1,yOfs-yScale,8,8,0,(void*)game_cursor,0); //place the cursor bitmap
501 dspl_show_bitmap(column*xScale+xOfs+1,yOfs-yScale, &gameCursor, 0 );
502 for (y_axis=0;y_axis<=MAX_Y_BOARD;y_axis++)
503 {
504 dspl_DrawLine( xOfs, yOfs+y_axis*yScale,
505 xOfs+MAX_X_BOARD*xScale, yOfs+y_axis*yScale);
506 }
507 for(x_axis=0;x_axis<=MAX_X_BOARD;x_axis++)
508 {
509 dspl_DrawLine( xOfs+x_axis*xScale, yOfs,
510 xOfs+x_axis*xScale, yOfs+MAX_Y_BOARD*yScale);
511 }
512
513 //go through the board-array and check for W or B and set the stones
514 for (y_axis=0;y_axis<MAX_Y_BOARD;y_axis++)
515 {
516 for(x_axis=0;x_axis<MAX_X_BOARD;x_axis++)
517 {
518 xPos = manOfsX+x_axis*xScale;
519 yPos = manOfsY+y_axis*yScale;
520 if(data->board_array[y_axis][x_axis] EQ 'W'){ //found white
521 //set white_stone bitmap
522 dspl_SetFgdColour( COL_R );
523 dspl_show_bitmap(xPos,yPos, whiteStone, 0 );
524 }
525 if(data->board_array[y_axis][x_axis] EQ 'B'){ //found black
526 //set black_stone bitmap
527 dspl_SetFgdColour( COL_G ); //0x00404040
528 dspl_show_bitmap(xPos,yPos, blackStone, 0 );
529 }
530 }
531 }
532 dspl_SetFgdColour( COL_RB );
533 dspl_SetBgdColour( COL_RG );
534 dspl_show_bitmap(GAME_NAMEPOSX1, GAME_NAMEPOSY1, &gameName1, 0 );
535 displayPosX = (SCREEN_SIZE_X/2);
536 temp = strlen((char*)playAgain);
537 //this if-clause is to set the bitmap, for win or lost game
538 if(winner EQ 'W'){
539 //human player wins, so set win bitmap
540 #ifdef LSCREEN
541 dspl_SetFgdColour( COL_BLK );
542 dspl_SetBgdColour( COL_TRANSPARENT );
543 Game_Result = TRUE;
544 softKeys_displayId(TxtYes,TxtNo,0,COLOUR_LIST_SUBMENU);
545 dspl_TextOut((displayPosX-((temp*CHAR_WIDTH)/2)),170,DSPL_TXTATTR_NORMAL,(char*)playAgain);
546 #endif
547 dspl_SetFgdColour( COL_RB );
548 dspl_SetBgdColour( COL_GB );
549 dspl_show_bitmap(GAME_WINPOSX1, GAME_WINPOSY1, &plWin1, 0 );
550 dspl_show_bitmap(GAME_WINPOSX2, GAME_WINPOSY2, &plWin2, 0 );
551 }
552 else
553 if(winner EQ 'B'){
554 //human player lost, so set lost bitmap
555 #ifdef LSCREEN
556 dspl_SetFgdColour( COL_BLK );
557 dspl_SetBgdColour( COL_TRANSPARENT );
558 Game_Result = TRUE;
559 softKeys_displayId(TxtYes,TxtNo,0,COLOUR_LIST_SUBMENU);
560 dspl_TextOut((displayPosX-((temp*CHAR_WIDTH)/2)),170,DSPL_TXTATTR_NORMAL,(char*)playAgain);
561 #endif
562 dspl_SetFgdColour( COL_RB );
563 dspl_SetBgdColour( COL_GB );
564 dspl_show_bitmap(GAME_WINPOSX1, GAME_WINPOSY1, &plLost1, 0 );
565 dspl_show_bitmap(GAME_WINPOSX2, GAME_WINPOSY2, &plLost2, 0 );
566 }
567 else
568 if(winner EQ 'N'){
569 //board is full, nobody (N) wins
570 #ifdef LSCREEN
571 dspl_SetFgdColour( COL_BLK );
572 dspl_SetBgdColour( COL_TRANSPARENT );
573 Game_Result = TRUE;
574 softKeys_displayId(TxtYes,TxtNo,0,COLOUR_LIST_SUBMENU);
575 dspl_TextOut((displayPosX-((temp*CHAR_WIDTH)/2)),170,DSPL_TXTATTR_NORMAL,(char*)playAgain);
576 #endif
577
578 dspl_SetFgdColour( COL_R );
579 dspl_SetBgdColour( COL_G );
580 dspl_show_bitmap(GAME_WINPOSX1, GAME_WINPOSY1, &draw1, 0 );
581 dspl_show_bitmap(GAME_WINPOSX2, GAME_WINPOSY2, &draw2, 0 );
582 }
583 else
584 {
585 dspl_SetFgdColour( COL_RB );
586 dspl_SetBgdColour( COL_RG );
587 dspl_show_bitmap(GAME_NAMEPOSX1, GAME_NAMEPOSY1, &gameName1, 0 );
588 dspl_show_bitmap(GAME_NAMEPOSX2, GAME_NAMEPOSY2, &gameName2, 0 );
589 dspl_show_bitmap(GAME_NAMEPOSX3, GAME_NAMEPOSY3, &gameName2, 0 );
590 }
591 break;
592
593 default:
594 return 0;
595 }
596
597 return 1;
598 }
599
600 /*******************************************************************************
601
602 $Function: four_in_a_row_kbd_cb
603
604 $Description:
605
606 $Returns:
607
608 $Arguments:
609
610 *******************************************************************************/
611
612 int four_in_a_row_kbd_cb (MfwEvt e, MfwKbd *k)
613 {
614
615 T_MFW_HND win = mfw_parent (mfw_header());
616 T_MFW_WIN * win_data = ((T_MFW_HDR *)win)->data;
617 T_four_in_a_row * data = (T_four_in_a_row *)win_data->user;
618
619 TRACE_EVENT ("four_in_a_row_kbd_cb()");
620
621 switch (k->code)
622 {
623 case KCD_HUP: //quit the game "four in a row"
624 case KCD_RIGHT: //quit the game "four in a row"
625 TRACE_EVENT ("quit four_in_a_row");
626 dspl_ClearAll(); //clear mobile screen
627 four_in_a_row_destroy (win); //destroy win-handler
628 break;
629
630 case KCD_MNULEFT:
631 case KCD_1:
632 if(winner EQ '0'){ //while nobody has won....
633 TRACE_EVENT ("KCD_1");
634 if(column > 0)
635 { //cursor must be greater than 0
636 column=column-1;
637 }
638 winShow(data->win);
639 }
640 break;
641 case KCD_MNUSELECT:
642 case KCD_2:
643 if(winner EQ '0'){ //while nobody has won....
644 TRACE_EVENT ("KCD_2");
645 drop_stone(data); //drop stone
646 }
647 winShow(data->win);
648 break;
649 case KCD_MNURIGHT:
650 case KCD_3:
651 if(winner EQ '0'){ //while nobody has won....
652 TRACE_EVENT ("KCD_3");
653 if(column<MAX_X_BOARD-1 ){ //cursor must be less than 50
654 column=column+1;
655 }
656 winShow(data->win);
657 }
658 break;
659 case KCD_LEFT:
660 if(Game_Result == TRUE)
661 {
662 Game_Result = FALSE;
663 four_in_a_row_destroy(win); //destroy win-handler
664 four_in_a_row_start(win,0);
665 }
666 else
667 Game_Info(win);
668 break;
669 }
670 return MFW_EVENT_CONSUMED;
671 }
672
673 /*******************************************************************************
674
675 $Function: four_in_a_row_aktivate
676
677 $Description: Starts the game function on user selection
678
679 $Returns: MFW_EVENT_CONSUMED if event handled, otherwise
680 MFW_EVENT_PASSED
681
682 $Arguments: menu, menu item
683
684 *******************************************************************************/
685 int four_in_a_row_aktivate(MfwMnu* m, MfwMnuItem* i)
686 {
687 T_four_in_a_row * data;
688 T_MFW_HND parent = mfwParent( mfw_header());
689 TRACE_EVENT("four_in_a_row_aktivate()");
690 four_in_a_row_start(parent,0);
691 return MFW_EVENT_CONSUMED;
692 }
693
694 /*******************************************************************************
695
696 $Function: drop_stone
697
698 $Description: decide whether a stone can be droped and where it can be droped
699
700 $Returns:
701
702 $Arguments: T_four_in_a_row
703
704 *******************************************************************************/
705 void drop_stone(T_four_in_a_row *data)
706 {
707 int drop_position; //position (y in current board column) where to drop the stone
708
709 TRACE_EVENT("drop_stone()");
710 request_stone=0; //white is on turn
711 drop_position=check_column(data,request_stone); //set the drop position for the white stone in the current white, board column
712 if(drop_position>=0){ //if the current column is not filled up set stone
713 data->board_array[drop_position][column]='W'; //white is first and set a 'W' in the virtual board for a white stone
714 check_for_winner(data,drop_position); //check whether the last move(white) was a win-move...
715 if(winner EQ '0'){ //...if not, then the mobile(black) is on turn
716 drop_position=mobile_thinking(data); //set the drop position for the black stone in the current black, board column
717 data->board_array[drop_position][column_black]='B'; //set a 'B' for in the virtual board for a black stone
718 check_for_winner(data,drop_position); //check whether the last move(black) was a win-move...
719 }
720 }
721 }
722
723 /*******************************************************************************
724
725 $Function: check_for_winner
726
727 $Description: checks the current drop position for a win-position
728
729 $Returns:
730
731 $Arguments: T_four_in_a_row
732
733 *******************************************************************************/
734 void check_for_winner(T_four_in_a_row *data, int check_out_position)
735 {
736 int check_with_this_color; //set the color to check for
737 int color_regulator; //helps to switch between both colors
738 int check_this_column; //declares the column to check for
739
740 TRACE_EVENT("check_for_winner()");
741 color_regulator=0; //at first, use white to check for
742 winner='0'; //at first we don't know who wins, so nobody is set as winner
743 while(color_regulator<2){ //while checking for white(0) and black(1) is not ready....
744 if(color_regulator EQ 0){ //if color_regulator is 0, the board will be checked for white stones ('W')
745 check_with_this_color='W';
746 }else{ //if color_regulator is 1, the board will be checked for black stones ('B')
747 check_with_this_color='B';
748 }
749
750 if(request_stone EQ 0){ //if the board will be checked for white, use column as the current column
751 check_this_column=column;
752 }else{ //if the board will be checked for black, use column_black as the current column
753 check_this_column=column_black;
754 }
755
756 /*Begin with the checks, the mobile checks for vertical, horizontal and diagonal possibilities*/
757 //check row
758 if(data->board_array[check_out_position][check_this_column-3] EQ check_with_this_color &&
759 data->board_array[check_out_position][check_this_column-2] EQ check_with_this_color &&
760 data->board_array[check_out_position][check_this_column-1] EQ check_with_this_color &&
761 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
762 check_this_column>=3 && check_this_column<=10){
763 winner=check_with_this_color; //set the current color to check for as the winner
764 break;
765 }else if(data->board_array[check_out_position][check_this_column-1] EQ check_with_this_color &&
766 data->board_array[check_out_position][check_this_column-2] EQ check_with_this_color &&
767 data->board_array[check_out_position][check_this_column+1] EQ check_with_this_color &&
768 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
769 check_this_column>=2 && check_this_column<=9){
770 winner=check_with_this_color; //set the current color to check for as the winner
771 break;
772 }else if(data->board_array[check_out_position][check_this_column+1] EQ check_with_this_color &&
773 data->board_array[check_out_position][check_this_column+2] EQ check_with_this_color &&
774 data->board_array[check_out_position][check_this_column+3] EQ check_with_this_color &&
775 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
776 check_this_column>=0 && check_this_column<=7){
777 winner=check_with_this_color; //set the current color to check for as the winner
778 break;
779 }else if(data->board_array[check_out_position][check_this_column-1] EQ check_with_this_color &&
780 data->board_array[check_out_position][check_this_column+1] EQ check_with_this_color &&
781 data->board_array[check_out_position][check_this_column+2] EQ check_with_this_color &&
782 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
783 check_this_column>=1 && check_this_column<=8){
784 winner=check_with_this_color; //set the current color to check for as the winner
785 break;
786 //check column
787 }else if(data->board_array[check_out_position+1][check_this_column] EQ check_with_this_color &&
788 data->board_array[check_out_position+2][check_this_column] EQ check_with_this_color &&
789 data->board_array[check_out_position+3][check_this_column] EQ check_with_this_color &&
790 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
791 check_out_position<=4){
792 winner=check_with_this_color; //set the current color to check for as the winner
793 break;
794 //check diagonal
795 }else if(data->board_array[check_out_position+1][check_this_column-1] EQ check_with_this_color &&
796 data->board_array[check_out_position+2][check_this_column-2] EQ check_with_this_color &&
797 data->board_array[check_out_position+3][check_this_column-3] EQ check_with_this_color &&
798 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
799 check_out_position<=4 && check_this_column>=3 && check_this_column<=10){
800 winner=check_with_this_color; //set the current color to check for as the winner
801 break;
802 }else if(data->board_array[check_out_position+1][check_this_column+1] EQ check_with_this_color &&
803 data->board_array[check_out_position+2][check_this_column+2] EQ check_with_this_color &&
804 data->board_array[check_out_position+3][check_this_column+3] EQ check_with_this_color &&
805 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
806 check_out_position<=4 && check_this_column>=0 && check_this_column<=7){
807 winner=check_with_this_color; //set the current color to check for as the winner
808 break;
809 }else if(data->board_array[check_out_position-1][check_this_column+1] EQ check_with_this_color &&
810 data->board_array[check_out_position-2][check_this_column+2] EQ check_with_this_color &&
811 data->board_array[check_out_position-3][check_this_column+3] EQ check_with_this_color &&
812 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
813 check_out_position>=3 && check_this_column>=0 && check_this_column<=7){
814 winner=check_with_this_color; //set the current color to check for as the winner
815 break;
816 }else if(data->board_array[check_out_position-1][check_this_column-1] EQ check_with_this_color &&
817 data->board_array[check_out_position-2][check_this_column-2] EQ check_with_this_color &&
818 data->board_array[check_out_position-3][check_this_column-3] EQ check_with_this_color &&
819 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
820 check_out_position>=3 && check_this_column>=3 && check_this_column<=10){
821 winner=check_with_this_color; //set the current color to check for as the winner
822 break;
823 }else if(data->board_array[check_out_position+1][check_this_column-1] EQ check_with_this_color &&
824 data->board_array[check_out_position-1][check_this_column+1] EQ check_with_this_color &&
825 data->board_array[check_out_position-2][check_this_column+2] EQ check_with_this_color &&
826 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
827 check_out_position<=6 && check_out_position>=2 && check_this_column>=1 && check_this_column<=8){
828 winner=check_with_this_color; //set the current color to check for as the winner
829 break;
830 }else if(data->board_array[check_out_position+1][check_this_column-1] EQ check_with_this_color &&
831 data->board_array[check_out_position+2][check_this_column-2] EQ check_with_this_color &&
832 data->board_array[check_out_position-1][check_this_column+1] EQ check_with_this_color &&
833 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
834 check_out_position<=5 && check_out_position>=1 && check_this_column>=2 && check_this_column<=9){
835 winner=check_with_this_color; //set the current color to check for as the winner
836 break;
837 }else if(data->board_array[check_out_position-1][check_this_column-1] EQ check_with_this_color &&
838 data->board_array[check_out_position+1][check_this_column+1] EQ check_with_this_color &&
839 data->board_array[check_out_position+2][check_this_column+2] EQ check_with_this_color &&
840 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
841 check_out_position<=5 && check_out_position>=1 && check_this_column>=1 && check_this_column<=8){
842 winner=check_with_this_color; //set the current color to check for as the winner
843 break;
844 }else if(data->board_array[check_out_position-1][check_this_column-1] EQ check_with_this_color &&
845 data->board_array[check_out_position-2][check_this_column-2] EQ check_with_this_color &&
846 data->board_array[check_out_position+1][check_this_column+1] EQ check_with_this_color &&
847 data->board_array[check_out_position][check_this_column] EQ check_with_this_color &&
848 check_out_position>=2 && check_out_position<=6 && check_this_column>=2 && check_this_column<=9){
849 winner=check_with_this_color; //set the current color to check for as the winner
850 break;
851 }else{
852 winner='0'; //no win-moves found, so nobody is the winner and the game goes on
853 }
854 color_regulator++; //set the check color one up (to black)
855 }
856 }
857 /*******************************************************************************
858
859 $Function: check_column
860
861 $Description: checks for already set stones
862
863 $Returns: int unused_position
864
865 $Arguments: T_four_in_a_row
866
867 *******************************************************************************/
868 int check_column(T_four_in_a_row *data, int where_from)
869 {
870 int unused_position; //is for a free drop position
871 int column_for_check; //column (vertical board line) to check for
872
873 if(where_from EQ 0){ //is the current game color(player) 0 then use column
874 column_for_check=column;
875 }else{ //is the current game color(player) 1 then use column_black
876 column_for_check=column_black;
877 }
878 unused_position=-9999;
879 for(y_runer=0;y_runer<MAX_Y_BOARD;y_runer++){ //test all vertical fields whether they are empty('0') or not
880 if(data->board_array[y_runer][column_for_check] EQ '0'){
881 unused_position=y_runer; //.this field is empty, so it is a unused position
882 }
883 }
884 return unused_position; //return the unused position
885 }
886
887
888 /*******************************************************************************
889
890 $Function: mobile_thinking
891
892 $Description: mobile moves
893
894 $Returns: drop position of black stone (drop_me)
895
896 $Arguments: T_four_in_a_row
897
898 *******************************************************************************/
899 int mobile_thinking(T_four_in_a_row *data)
900 {
901 int position_score[11]; //this array takes the scoring values of each column in the game board
902 int drop_position; //drop position for stone
903 int drop_me; //buffer value
904 int scores[4]; //this array keeps the scores for row, column and diagonals
905 int add_random_score;
906
907 TRACE_EVENT("mobile_thinking()");
908
909 request_stone=1; //black is
910 //check for good spots to drop the black stone
911 for(x_runer=0;x_runer<MAX_X_BOARD;x_runer++){
912 //found the possible drop position
913 column_black=x_runer; //set the x_runer to the current column (column_black)
914 drop_position=check_column(data,request_stone); //check for possible drop positions
915 if(drop_position>=0){ //if there is a possible drop position.....
916 //check the scoring of the current point
917 add_random_score=random_scoring();
918 data->board_array[drop_position][x_runer]='B'; //set a test black stone
919 scores[0]=check_line(data,x_runer,drop_position,1,0,0); //scores row
920 scores[1]=check_line(data,x_runer,drop_position,1,1,0); //scores diagonal right-up/left-down
921 scores[2]=check_line(data,x_runer,drop_position,1,-1,0); //scores diagonal left-up/right-down
922 scores[3]=check_line(data,x_runer,drop_position,0,1,0); //scores down(column)
923 position_score[x_runer]=scores[0]+scores[1]+scores[2]+scores[3]; //count all scores together to one total score
924 if(drop_position-1 >=0){ //Is it possible to set a future stone here? If Yes go on...
925 data->board_array[drop_position-1][x_runer]='W'; //set a test white stone for a possible next opponent move
926 scores[0]=check_line(data,x_runer,drop_position-1,1,0,1); //scores row
927 scores[1]=check_line(data,x_runer,drop_position-1,1,1,1); //scores diagonal right-up/left-down
928 scores[2]=check_line(data,x_runer,drop_position-1,1,-1,1); //scores diagonal left-up/right-down
929 scores[3]=check_line(data,x_runer,drop_position-1,0,1,1); //scores down(column)
930 position_score[x_runer]=position_score[x_runer]-scores[0]-scores[1]-scores[2]-scores[3]+add_random_score; //substraction of the future score from the normal score
931 data->board_array[drop_position-1][x_runer]='0'; //remove test white stone
932 }
933 data->board_array[drop_position][x_runer]='0'; //remove test black stone
934 }else{ //if there is no possible drop position set the score to -1
935 position_score[x_runer]=-9999;
936 }
937 }
938
939 drop_me=-9999; //buffer is set to absolutely minus
940 column_black=-9999; //position of black cursor is left outer side of board
941 for(x_runer=0;x_runer<MAX_X_BOARD;x_runer++){ //goes through the scoring array to find the highest score
942 if(position_score[x_runer]>drop_me){
943 drop_me=position_score[x_runer];
944 column_black=x_runer; //set the x_runer to the current column(column_black)
945 drop_position=check_column(data,request_stone); //this is the best drop position for the mobile
946 }
947 }
948 if(column_black EQ -9999){ //if the column is -1, then the game board is filled up and nobody has won
949 TRACE_EVENT("Board Full!!!");
950 winner='N'; //set winner to nobody (N)
951 }
952 return drop_position; //return the mobile drop position
953 }
954
955 /*******************************************************************************
956
957 $Function: check_line
958
959 $Description: set score points for the mobile, so the mobile knows where to set the next stone
960
961 $Returns: total_score
962
963 $Arguments: T_four_in_a_row, x_value, drop_position, dx, dy, where_from
964
965 *******************************************************************************/
966 int check_line(T_four_in_a_row *data, int x_value, int y_value, int dx, int dy, BOOL where_from)
967 {
968 int lSc,nSc,oSc,total_score,sx,sy,i,j;
969 int pl_nSc; //no of empty squares that have a man under them (i.e. we/opponent can use next shot)
970 total_score=0;
971 for (i=0;i<4;i++){
972 sx = x_value-i*dx;
973 sy = y_value-i*dy;
974 lSc=0;
975 nSc=0; pl_nSc=0;
976 oSc=0;
977 for (j=0;j<4;j++){
978 if ((sx<0) || (sx>MAX_X_BOARD) ||(sy<0) || (sy>MAX_Y_BOARD)){
979 lSc = -1;
980 }else if (lSc>=0){
981 if(where_from EQ 0){
982 if (data->board_array[sy][sx] EQ 'B'){
983 lSc++;
984 }else if (data->board_array[sy][sx] EQ '0'){
985 nSc++;
986 if ((sy EQ MAX_Y_BOARD) || (data->board_array[sy+1][sx] NEQ '0'))
987 pl_nSc++;
988 }else if (data->board_array[sy][sx] EQ 'W'){
989 oSc++;
990
991 }else //edge of board found
992 lSc=-1;
993 sx = sx+dx;
994 sy = sy+dy;
995 }else{
996 if (data->board_array[sy][sx] EQ 'W'){
997 lSc++;
998 }else if (data->board_array[sy][sx] EQ '0'){
999 nSc++;
1000 if ((sy EQ MAX_Y_BOARD) || (data->board_array[sy+1][sx] NEQ '0'))
1001 pl_nSc++;
1002 }else if (data->board_array[sy][sx] EQ 'B'){
1003 oSc++;
1004
1005 }else //edge of board found
1006 lSc=-1;
1007 sx = sx+dx;
1008 sy = sy+dy;
1009 }
1010 }
1011 }
1012 if (lSc >= 0){
1013 if (lSc EQ 4){
1014 return(9999);//got 4 in a row.
1015 }else if (oSc EQ 3) //and ISc==1
1016 {
1017 // 3 opp men - good spot!
1018 if(where_from EQ 0){
1019 total_score = total_score + 1000; //this is for the normal, current position score
1020 }else{
1021 total_score = -total_score - 1000; //this is for the possible future score, it must be minus, because it will be substracted from normal score
1022 }
1023 }else if ((lSc EQ 3) && (nSc EQ 1)){
1024 //playing here will form 3 in a row and a blank - good spot
1025 if (pl_nSc EQ 0) //can't reach the 4th position
1026 total_score = total_score + 75;
1027 else
1028 total_score = total_score + 125;//better if we can reach 4th position
1029 }else if ((oSc EQ 2) && (nSc EQ 1)){
1030 // 2 opp men + 1 blank- good spot!
1031 if (pl_nSc EQ 0) //can't reach the 4th position-not too bad
1032 total_score = total_score + 50;
1033 else
1034 total_score = total_score + 200;//can get to both positions - have to block.
1035 }else if ((lSc EQ 2) && (nSc EQ 2)){
1036 // 2 in a row and 2 blanks - OK spot
1037 if (pl_nSc EQ 0) //can't reach the 3rd or 4th position-not too good
1038 total_score = total_score + 20;
1039 else if (pl_nSc EQ 1) //can reach one of the 3rd or 4th position - good
1040 total_score = total_score + 45;
1041 else if (pl_nSc EQ 2) //can reach both 3rd and 4th position - very good
1042 total_score = total_score + 95;
1043 }else if ((lSc EQ 1) && (nSc EQ 3)){
1044 // 1 in a row and 3 blanks - OK spot, better if we can reach the other 3 points.
1045 total_score = total_score + 2*(pl_nSc+1); //pl_nSc=0,1,2 or 3 sc=sc+2,4,6 or 8
1046 }
1047 //else //line is neither good nor bad.
1048 }
1049 else //line is not valid
1050 total_score = total_score - 1;
1051 }
1052 return(total_score);
1053 }
1054 /*******************************************************************************
1055
1056 $Function: check_line
1057
1058 $Description: generates a random number to add on the field scores
1059
1060 $Returns: random_score_result
1061
1062 $Arguments:
1063
1064 *******************************************************************************/
1065 int random_scoring(void)
1066 {
1067 return(rand()%100);
1068 }
1069
1070
1071
1072 #define MAX_TET_X 11
1073 #define MAX_TET_Y 20
1074
1075 typedef struct
1076 {
1077
1078 T_MMI_CONTROL mmi_control; // common control parameter
1079 T_MFW_HND win;
1080 T_MFW_HND hKbd;
1081 T_MFW_HND menu;
1082 T_MFW_HND parent_win;
1083 T_MFW_HND info_tim;
1084
1085 int dropTime;
1086 int maxDropTime;
1087 int timeStep;
1088
1089 int xPos;
1090 int yPos;
1091
1092 int px;
1093 int py;
1094 int shapeId;
1095 char shapeStr[20];
1096 int rotateId;
1097
1098 int score;
1099 int level;
1100 int linesToGo;
1101
1102 int resetSpeed;
1103
1104 int gameOver;
1105
1106 char tetrisScreen[MAX_TET_X][MAX_TET_Y];
1107
1108 } T_TETRIS;
1109
1110
1111 static MfwHnd TetrisCreate(MfwHnd hParentWin);
1112 static void TetrisExecCb (MfwHnd hWin, USHORT uiE, SHORT iValue, void *pParameter);
1113 static int TetrisKbdCb (MfwEvt uiE, MfwKbd *psK);
1114 static int tetris_tim_cb(MfwEvt e, MfwTim *t);
1115 static int TetrisWinCb (MfwEvt uiE, MfwWin *psWin);
1116
1117
1118 #define E_INIT 0x5000
1119 #define E_EXIT 0x5001
1120
1121 void initTetGame(T_TETRIS *data)
1122 {
1123 int x,y;
1124 for (y=0;y<MAX_TET_Y;y++)
1125 {
1126 for (x=0;x<MAX_TET_X;x++)
1127 data->tetrisScreen[x][y]=' ';
1128 data->tetrisScreen[0][y]='#';
1129 data->tetrisScreen[MAX_TET_X-1][y]='#';
1130
1131 }
1132 for (x=0;x<MAX_TET_X;x++)
1133 data->tetrisScreen[x][MAX_TET_Y-1]='#';
1134 }
1135
1136 #define MAX_SHAPE 7
1137 void tetris_getShape(int shapeId, int rotate, char* shapeStr)
1138 {
1139 int j,k;
1140 int index;
1141 const char* tetShape[4*4*MAX_SHAPE] =
1142 { " ", " A ", " B ", " C ", " ", "F ", " G ",
1143 "EEEE", " AA ", " BB ", "CCC ", " DD ", "FFF ", "GGG ",
1144 " ", " A ", " B ", " ", " DD ", " ", " ",
1145 " ", " ", " ", " ", " ", " ", " ",
1146 " E ", " AA ", "BB ", " C ", " ", " FF ", " G ",
1147 " E ", "AA ", " BB ", " CC ", " DD ", " F ", " G ",
1148 " E ", " ", " ", " C ", " DD ", " F ", " GG ",
1149 " E ", " ", " ", " ", " ", " ", " ",
1150 " ", " A ", " B ", " ", " ", " ", " ",
1151 "EEEE", " AA ", " BB ", "CCC ", " DD ", "FFF ", "GGG ",
1152 " ", " A ", " B ", " C ", " DD ", " F ", "G ",
1153 " ", " ", " ", " ", " ", " ", " ",
1154 " E ", " AA ", "BB ", " C ", " ", " F ", "GG ",
1155 " E ", "AA ", " BB ", "CC ", " DD ", " F ", " G ",
1156 " E ", " ", " ", " C ", " DD ", "FF ", " G ",
1157 " E ", " ", " ", " ", " ", " ", " "
1158 };
1159
1160
1161 for (k=0;k<4;k++)
1162 {
1163 index = rotate*4*MAX_SHAPE+k*MAX_SHAPE;
1164 for (j=0;j<4;j++)
1165 shapeStr[j+k*4] = tetShape[index+shapeId][j];
1166 }
1167 }
1168
1169 int tetris_getNextShapeId( void )
1170 {
1171 static int shapeIndex = 0;
1172 shapeIndex = (shapeIndex+1) % MAX_SHAPE;
1173 return (shapeIndex);
1174 }
1175
1176
1177
1178 void tetris_getNextShape(T_TETRIS *data)
1179 {
1180 data->shapeId = tetris_getNextShapeId( );
1181 data->rotateId = 0;
1182 tetris_getShape(data->shapeId, data->rotateId, data->shapeStr);
1183 data->px = (MAX_TET_X-2)/2;
1184 data->py = 0;
1185 }
1186
1187 void tetris_getNextLevel(T_TETRIS *data)
1188 {
1189 initTetGame(data);
1190 tetris_getNextShape(data);
1191 data->level = data->level+1;
1192 data->linesToGo = 5*(data->level+1);
1193 data->resetSpeed = 0;
1194 data->maxDropTime = (120-data->level*5);
1195 }
1196
1197 void initTetrisData( T_TETRIS *data )
1198 {
1199 data->level = 0;
1200 data->score = 0;
1201 data->gameOver = 0;
1202 tetris_getNextLevel(data);
1203 }
1204
1205 void dspl_FillRect( int x1, int y1, int sx, int sy)
1206 {
1207 dspl_DrawFilledBgdRect(x1,y1,x1+sx,y1+sy);
1208 }
1209
1210 void tetris_drawScreen( int allScreen, T_TETRIS *data)
1211 {
1212 int x1,y1,x2,y2;
1213 int bCol;
1214 int xOfs =5;
1215 int yOfs=10;
1216 int xOfs2=30;
1217 int yOfs2=10;
1218 int sx,sy;
1219 int px,py;
1220 // U32 oldfCol=0; // RAVI
1221 // U32 oldbCol=0; // RAVI
1222 int x = data->px;
1223 int y = data->py;
1224
1225 // char dbg[80]; // RAVI
1226
1227
1228 #ifdef LSCREEN
1229 //Calculate size based on the screen properties
1230 sx = (SCREEN_SIZE_X-xOfs-xOfs2)/MAX_TET_X;
1231 sy = (SCREEN_SIZE_Y-yOfs-yOfs2-Mmi_layout_softkeyHeight())/MAX_TET_Y;
1232 #else
1233 //Screen is very small - ensure shapes are as large as possible
1234 sy = SCREEN_SIZE_Y/MAX_TET_Y;
1235 sx = SCREEN_SIZE_X/MAX_TET_X;
1236 if (sx >sy+1)
1237 sx = sy+1;
1238 xOfs = 5;
1239 xOfs2 = SCREEN_SIZE_X - (sx*MAX_TET_X+xOfs);
1240 yOfs = 0;
1241 yOfs2 = SCREEN_SIZE_Y - (sy*MAX_TET_Y+xOfs);
1242 #endif
1243 //allScreen= 1;
1244
1245 resources_setColour(COLOUR_GAME);
1246
1247 if (allScreen)
1248 { //redraw everything
1249 x1 = 0;
1250 y1 = 0;
1251 x2 = MAX_TET_X;
1252 y2 = MAX_TET_Y;
1253
1254 }
1255 else //just draw+1 box around current man
1256 {
1257 x1 = x-1;
1258 y1 = y-1;
1259 x2 = x+5;
1260 y2 = y+4;
1261 if (x1<1)x1=1;
1262 if (y1<0)y1=0;
1263 if (x2>MAX_TET_X-1) x2=MAX_TET_X-1;
1264 if (y2>MAX_TET_Y-1) y2=MAX_TET_Y-1;
1265 }
1266
1267 #ifndef COLOURDISPLAY
1268 dspl_Clear (xOfs+x1*sx,yOfs+y1*sy,xOfs+x2*sx-1,yOfs+y2*sy-1);
1269 #endif
1270 for (px = x1;px<x2;px++)
1271 {
1272 for (py = y1;py<y2;py++)
1273 {
1274 char boardChr = data->tetrisScreen[px][py];
1275 if ((px >= x ) && (px < x+4) &&
1276 (py >= y ) && (py < y+4))
1277 {
1278 int shapeX,shapeY;
1279 shapeX = px-x;
1280 shapeY = py-y;
1281 if (data->shapeStr[shapeX+shapeY*4] != ' ')
1282 boardChr = data->shapeStr[shapeX+shapeY*4];
1283 }
1284 #ifdef COLOURDISPLAY
1285 switch (boardChr)
1286 {
1287 case '#': bCol = 0x00FFFFFF; break;
1288 case ' ': bCol = 0x00404040; break;
1289 case 'A': bCol = 0x000000FF; break;
1290 case 'B': bCol = 0x0000FF00; break;
1291 case 'C': bCol = 0x00FF0000; break;
1292 case 'D': bCol = 0x0000FFFF; break;
1293 case 'E': bCol = 0x00FF00FF; break;
1294 case 'F': bCol = 0x00FFFF00; break;
1295 default: bCol = 0x00FFFFFF; break;
1296 }
1297 dspl_SetBgdColour(bCol);
1298 dspl_FillRect(xOfs+px*sx,yOfs+py*sy,sx,sy);
1299 // dspl_SetFgdColour(0x00802040);
1300 if (boardChr != ' ')
1301 dspl_DrawRect (xOfs+px*sx,yOfs+py*sy,xOfs+px*sx+sx-1,yOfs+py*sy+sy-1);
1302 #else
1303 if (boardChr != ' ')
1304 dspl_DrawRect (xOfs+px*sx,yOfs+py*sy,xOfs+px*sx+sx-1,yOfs+py*sy+sy-1);
1305 #endif
1306 }
1307 }
1308 if (data->gameOver)
1309 {
1310 int oldfCol = dspl_SetFgdColour(0x00FFFF00);
1311 dspl_SetBgdColour(0x008000FF);
1312 dspl_FillRect(xOfs+sx*3-5,yOfs+sy*3-5, xOfs+sx*3+5+6*4,yOfs+sy*3+5+18);
1313 dspl_TextOut(xOfs+sx*3,yOfs+sy*3, 0, "GAME");
1314 dspl_TextOut(xOfs+sx*3,yOfs+sy*3+Mmi_layout_line_height()+4, 0, "OVER");
1315 dspl_SetFgdColour(oldfCol);
1316
1317 }
1318 resources_restoreColour();
1319 }
1320
1321
1322
1323 int tetris_addShapeToScreen(T_TETRIS *data)
1324 {
1325 int x,y;
1326 for (x=0;x<4;x++)
1327 for (y=0;y<4;y++)
1328 if (data->shapeStr[x+y*4] != ' ')
1329 {
1330 if (data->tetrisScreen[data->px+x][data->py+y]!= ' ')
1331 return(1);
1332 else
1333 data->tetrisScreen[data->px+x][data->py+y] = data->shapeStr[x+y*4];
1334 }
1335 return(0);
1336
1337 }
1338
1339 int tetris_testForCompleteLines( T_TETRIS *data )
1340 {
1341 int nLines=0;
1342 int x,y;
1343 int blanks;
1344 for (y=MAX_TET_Y-2;y>0;y--)
1345 {
1346 blanks = 0;
1347
1348 for (x=1;x<MAX_TET_X-1;x++)
1349 {
1350 if (data->tetrisScreen[x][y] == ' ')
1351 blanks++;
1352 if (nLines >0)
1353 data->tetrisScreen[x][y+nLines] = data->tetrisScreen[x][y];
1354 }
1355 if (blanks==0)
1356 nLines++;
1357
1358 }
1359 return (nLines);
1360 }
1361
1362
1363 void tetris_testGameOver( T_TETRIS *data )
1364 {
1365 int linesComplete;
1366
1367 data->gameOver = tetris_addShapeToScreen(data);
1368 if (!data->gameOver)
1369 {
1370
1371 linesComplete = tetris_testForCompleteLines(data);
1372 if (linesComplete >0)
1373 {
1374 data->score = data->score + linesComplete*linesComplete;
1375 data->linesToGo = data->linesToGo - linesComplete;
1376 if (data->linesToGo <0)
1377 tetris_getNextLevel(data);
1378 }
1379 tetris_getNextShape(data);
1380 }
1381 }
1382
1383
1384
1385
1386
1387 void tetris_destroy (T_MFW_HND own_window)
1388 {
1389 T_MFW_WIN * win = ((T_MFW_HDR *)own_window)->data;
1390 T_TETRIS * data = (T_TETRIS *)win->user;
1391
1392 TRACE_EVENT ("tetris_destroy()");
1393
1394 if (own_window == NULL)
1395 {
1396 TRACE_EVENT ("Error :- Called with NULL Pointer");
1397 return;
1398 }
1399
1400 if (data)
1401 {
1402 /*
1403 * Exit ICON & KEYBOARD Handle
1404 */
1405 kbdDelete (data->hKbd);
1406 timDelete(data->info_tim);
1407 /*
1408 * Delete WIN Handler
1409 */
1410 winDelete (data->win);
1411 /*
1412 * Free Memory
1413 */
1414 FREE_MEMORY ((void *)data, sizeof (T_TETRIS));
1415 }
1416 }
1417
1418
1419
1420 int MmiTetrisStart(void )
1421 {
1422 MfwHnd hWin;
1423
1424 MfwHnd hParentWin = mfwParent(mfwHeader());
1425
1426 TRACE_FUNCTION ("TetrisStart()");
1427
1428 hWin = TetrisCreate (hParentWin);
1429
1430 if (hWin NEQ NULL)
1431 {
1432 SEND_EVENT (hWin, E_INIT, NULL, NULL);
1433 }
1434
1435 return 1;
1436 }
1437
1438 void initTetrisData( T_TETRIS *data );
1439 static MfwHnd TetrisCreate(MfwHnd hParentWin)
1440 {
1441 T_TETRIS *psData = (T_TETRIS *)ALLOC_MEMORY (sizeof( T_TETRIS));
1442 MfwWin *psWin;
1443 MfwWinAttr *win_attr;
1444
1445 TRACE_FUNCTION ("TetrisCreate()");
1446
1447 if (psData == NULL)
1448 {
1449 TRACE_EVENT ("ALLOC_MEMORY() failed");
1450 return NULL;
1451 }
1452
1453 win_attr = (MfwWinAttr *) ALLOC_MEMORY (sizeof(MfwWinAttr));
1454 if (win_attr)
1455 {
1456 win_attr->win.px = 0;
1457 win_attr->win.py = 0;
1458 win_attr->win.sx = SCREEN_SIZE_X;
1459 win_attr->win.sy = SCREEN_SIZE_Y;
1460 }
1461 psData->win = winCreate (hParentWin, win_attr, E_WIN_VISIBLE, (T_MFW_CB)TetrisWinCb);
1462 if (psData->win == NULL)
1463 {
1464 mfwFree((U8*) win_attr, sizeof(MfwWinAttr));
1465 FREE_MEMORY((void *)psData, sizeof (T_TETRIS));
1466 return NULL;
1467 }
1468 psData->mmi_control.dialog = (T_DIALOG_FUNC)TetrisExecCb;
1469 psData->mmi_control.data = psData;
1470 psData->timeStep = 150;
1471 psData->maxDropTime = 120;
1472 psData->dropTime = psData->maxDropTime;
1473 psWin = ((MfwHdr *)psData->win)->data;
1474 psWin->user = (void *)psData;
1475 psData->parent_win = hParentWin;
1476 initTetrisData( psData );
1477
1478 return psData->win;
1479 }
1480
1481 static int TetrisWinCb (MfwEvt uiE, MfwWin *psWin)
1482 {
1483 T_TETRIS *psData = (T_TETRIS *)psWin->user;
1484
1485 TRACE_FUNCTION ("TetrisWinCb()");
1486
1487 switch (uiE)
1488 {
1489 case MfwWinVisible:
1490 dspl_ResetWindow();
1491 dspl_SetBgdColour(0x000000FF);
1492 dspl_Clear(0,0,SCREEN_SIZE_X-1,SCREEN_SIZE_Y-1 );
1493 tetris_drawScreen( 1, psData);
1494
1495 break;
1496
1497 case MfwWinFocussed:
1498 case MfwWinDelete:
1499 default:
1500 return MFW_EVENT_REJECTED;
1501 }
1502 TRACE_FUNCTION ("TetrisWinCb() - end");
1503 return MFW_EVENT_CONSUMED;
1504 }
1505
1506 static void TetrisExecCb (MfwHnd hWin, USHORT uiE, SHORT iValue, void *pParameter)
1507 {
1508 MfwWin *psWin = ((MfwHdr *) hWin)->data;
1509 T_TETRIS *psData = (T_TETRIS *)psWin->user;
1510
1511 TRACE_FUNCTION ("TetrisExecCb()");
1512
1513 switch (uiE)
1514 {
1515 case E_INIT:
1516
1517 psData->info_tim = timCreate(hWin, psData->timeStep, (MfwCb)tetris_tim_cb);
1518 psData->hKbd = kbdCreate(psData->win, KEY_ALL, (MfwCb)TetrisKbdCb);
1519 timStart(psData->info_tim);
1520
1521 /* */
1522 winShow(hWin);
1523
1524 break;
1525
1526 case E_EXIT:
1527 tetris_destroy(hWin);
1528 break;
1529
1530 default:
1531 return;
1532 }
1533
1534 return;
1535 }
1536
1537
1538 static int tetris_checkPos( T_TETRIS *data, int px, int py, char* shape)
1539 {
1540 int x,y;
1541 for (x=0;x<4;x++)
1542 for (y=0;y<4;y++)
1543 if (shape[x+y*4] != ' ')
1544 {
1545 if (data->tetrisScreen[px+x][py+y]!= ' ')
1546 return(1);
1547 }
1548 return(0);
1549 }
1550
1551 static int tetris_moveDown(T_TETRIS *data,int *px, int *py)
1552 {
1553 int cannotMove;
1554 cannotMove = tetris_checkPos(data,*px,*py+1,data->shapeStr);
1555 if (cannotMove)
1556 return (1);
1557 else
1558 *py = *py+1;
1559 return (0);
1560 }
1561 static int tetris_moveLeft(T_TETRIS *data, int *px, int *py)
1562 {
1563 int cannotMove;
1564 cannotMove = tetris_checkPos(data,*px-1,*py,data->shapeStr);
1565 if (cannotMove)
1566 return (1);
1567 else
1568 *px = *px-1;
1569 return (0);
1570 }
1571 static int tetris_moveRight( T_TETRIS *data, int *px, int *py)
1572 {
1573 int cannotMove;
1574 cannotMove = tetris_checkPos(data,*px+1,*py,data->shapeStr);
1575 if (cannotMove)
1576 return (1);
1577 else
1578 *px = *px+1;
1579 return (0);
1580 }
1581
1582 static int tetris_rotateLeft( T_TETRIS *data, int *px, int *py )
1583 {
1584 int i;
1585 int cannotMove;
1586 char tmpShape[20];
1587 tetris_getShape(data->shapeId,(data->rotateId+1)%4,tmpShape);
1588 cannotMove = tetris_checkPos(data,*px,*py,tmpShape);
1589 if (cannotMove)
1590 return (1);
1591 for (i=0;i<16;i++)
1592 data->shapeStr[i] = tmpShape[i];
1593 data->rotateId = (data->rotateId+1)%4;
1594 return (0);
1595 }
1596
1597 static int tetris_rotateRight( T_TETRIS *data, int *px, int *py )
1598 {
1599 int i;
1600 int cannotMove;
1601 char tmpShape[20];
1602 tetris_getShape(data->shapeId,(data->rotateId+3)%4,tmpShape);
1603 cannotMove = tetris_checkPos(data,*px,*py,tmpShape);
1604 if (cannotMove)
1605 return (1);
1606 for (i=0;i<16;i++)
1607 data->shapeStr[i] = tmpShape[i];
1608 data->rotateId = (data->rotateId+3)%4;
1609 return (0);
1610 }
1611 #define KEY_TET_MOVELEFT KCD_1
1612 #define KEY_TET_MOVERIGHT KCD_3
1613 #define KEY_TET_ROTATELEFT KCD_4
1614 #define KEY_TET_ROTATERIGHT KCD_6
1615 #define KEY_TET_DROPALL KCD_5
1616 #define KEY_TET_DROP KCD_2
1617
1618
1619 static int TetrisKbdCb (MfwEvt uiE, MfwKbd *psK)
1620 {
1621 MfwHnd hWin = mfwParent(mfwHeader());
1622 MfwWin *psWin = ((MfwHdr *)hWin)->data;
1623 T_TETRIS *psData = (T_TETRIS *)psWin->user;
1624 int cannotMove=0;
1625
1626
1627 TRACE_FUNCTION ("TetrisKbdCb()");
1628 /***************************Go-lite Optimization changes Start***********************/
1629 // Aug 16, 2004 REF: CRR 24323 Deepa M.D
1630 TRACE_EVENT_P1 ("Code : %d",(int)psK->code);
1631 /***************************Go-lite Optimization changes Start***********************/
1632
1633
1634 switch(psK->code )
1635 {
1636 case KEY_TET_MOVELEFT:
1637 case KCD_MNULEFT:
1638 tetris_moveLeft(psData,&psData->px,&psData->py);
1639 break;
1640 case KEY_TET_MOVERIGHT:
1641 case KCD_MNURIGHT:
1642 tetris_moveRight(psData,&psData->px,&psData->py);
1643 break;
1644 case KEY_TET_ROTATELEFT:
1645 tetris_rotateLeft(psData,&psData->px,&psData->py);
1646 break;
1647 case KCD_MNUSELECT:
1648 case KEY_TET_ROTATERIGHT:
1649 tetris_rotateRight(psData,&psData->px,&psData->py);
1650 break;
1651 case KEY_TET_DROP:
1652 cannotMove = tetris_moveDown(psData,&psData->px,&psData->py);
1653 if (cannotMove)
1654 tetris_testGameOver( psData );
1655 break;
1656 case KEY_TET_DROPALL:
1657 while(tetris_moveDown(psData,&psData->px,&psData->py) ==0)
1658 { //loop until we hit the bottom
1659
1660 }
1661 cannotMove = 1;
1662 tetris_testGameOver( psData );
1663 break;
1664
1665
1666 case KCD_RIGHT:
1667 SEND_EVENT (hWin, E_EXIT, 0, 0);
1668 return MFW_EVENT_CONSUMED;
1669
1670 default:
1671
1672 return MFW_EVENT_CONSUMED;
1673 }
1674 tetris_drawScreen(cannotMove, psData);
1675
1676 TRACE_FUNCTION ("TetrisKbdCb()-end");
1677 return MFW_EVENT_CONSUMED;
1678 }
1679
1680 static int tetris_tim_cb(MfwEvt e, MfwTim *t)
1681 {
1682 T_MFW_HND win = mfw_parent (mfw_header());
1683 T_MFW_WIN * win_data = ((T_MFW_HDR *)win)->data;
1684 T_TETRIS * data = (T_TETRIS *)win_data->user;
1685 static int nCycles = 0;
1686 int cannotMove;
1687
1688 char bfr[80];
1689 nCycles = nCycles+ data->timeStep;
1690 if (nCycles > 1000)
1691 {
1692 nCycles = nCycles - 1000;
1693 data->maxDropTime = data->maxDropTime-1;
1694 }
1695 TRACE_EVENT("tetris_tim_cb");
1696 data->dropTime = data->dropTime - data->timeStep;
1697 if (data->dropTime < 0)
1698 {
1699 if (data->maxDropTime > 90)
1700 data->dropTime = data->dropTime+75*10;
1701 else if (data->maxDropTime > 60)
1702 data->dropTime = data->dropTime+(60+(data->maxDropTime-60)/2)*10;
1703 else if (data->maxDropTime > 30)
1704 data->dropTime = data->dropTime+data->maxDropTime*10;
1705 else
1706 data->dropTime = data->dropTime+(data->maxDropTime+90)/4*10;
1707
1708 if (data->dropTime < data->timeStep)
1709 data->dropTime = data->timeStep;
1710 else if (data->dropTime < data->timeStep)
1711 data->dropTime = data->timeStep;
1712
1713 resources_setColour(COLOUR_GAME);
1714 sprintf(bfr,"%d ",data->score);
1715 dspl_TextOut(SCREEN_SIZE_X-30 ,10, 0, bfr);
1716 sprintf(bfr,"%d ",data->linesToGo);
1717 dspl_TextOut(SCREEN_SIZE_X-30 ,12+Mmi_layout_line_height(), 0, bfr);
1718 resources_restoreColour();
1719 cannotMove = tetris_moveDown(data,&data->px,&data->py);
1720 tetris_getNextShapeId( );//To randomize it
1721
1722 if (cannotMove)
1723 {
1724 tetris_testGameOver( data );
1725 }
1726 tetris_drawScreen(cannotMove, data);
1727 }
1728
1729 timStart(data->info_tim);
1730 TRACE_EVENT("tetris_tim_cb-end");
1731 return 1;
1732 }
1733
1734 T_MFW_HND Game_Info(T_MFW_HND parent_window)
1735 {
1736 T_MFW_HND win = ShowGame_Information(parent_window);
1737 TRACE_FUNCTION("ShowVerion()");
1738 if (win NEQ NULL)
1739 {
1740 SEND_EVENT (win, SHOWGAMEINFO_INIT, 0, 0);
1741 }
1742
1743 return win;
1744 }
1745
1746 static T_MFW_HND ShowGame_Information(MfwHnd parent_window)
1747 {
1748 tShowInfo* data = (tShowInfo*)ALLOC_MEMORY (sizeof (tShowInfo));
1749 T_MFW_WIN* win;
1750
1751 if (data EQ NULL)
1752 {
1753 return NULL;
1754 }
1755
1756 // Create the window handler
1757 data->win = win_create (parent_window, 0, E_WIN_VISIBLE, NULL);
1758 if (data->win EQ NULL)
1759 {
1760 return NULL;
1761 }
1762
1763 // connect the dialog data to the MFW window
1764 data->mmi_control.dialog = (T_DIALOG_FUNC)ShowGame_DialogCB;
1765 data->mmi_control.data = data;
1766
1767 win = ((T_MFW_HDR *)data->win)->data;
1768 win->user = (void *)data;
1769 data->parent_win = parent_window;
1770
1771 return data->win;
1772 }
1773
1774 static void ShowGame_DialogCB(T_MFW_HND win, USHORT e, SHORT identifier, void *parameter)
1775 {
1776 T_MFW_WIN *win_data = ((T_MFW_HDR *) win)->data;
1777 tShowInfo* data = (tShowInfo*) win_data->user;
1778 /* SPR#1428 - SH - New editor data */
1779 #ifdef NEW_EDITOR
1780 // T_AUI_EDITOR_DATA editor_data; // RAVI
1781 #else /* NEW_EDITOR */
1782 // T_EDITOR_DATA editor_data; // RAVI
1783 #endif /* NEW_EDITOR */
1784
1785 switch (e)
1786 {
1787 case SHOWGAMEINFO_INIT:
1788 {
1789 strcat(data->buffer, info);
1790
1791 ShowGameInfoEditor(win);
1792
1793 /* SPR#1428 - SH - New editor changes */
1794 #ifdef NEW_EDITOR
1795 data->editor_data.Callback = (T_AUI_EDIT_CB)ShowInfoCB;
1796 AUI_edit_Start(win, &(data->editor_data));
1797 #else /* NEW_EDITOR */
1798 data->editor_data.Callback = (T_EDIT_CB)ShowInfoCB;
1799 editor_start(win, &(data->editor_data));
1800 #endif /* NEW_EDITOR */
1801
1802 winShow(data->win);
1803 }
1804 break;
1805
1806 default:
1807 {
1808 TRACE_EVENT("Show Game Info : Unknown Event");
1809 }
1810 break;
1811 }
1812 }
1813
1814 void ShowGameInfoEditor (T_MFW_HND win)
1815 {
1816 T_MFW_WIN *win_data = ((T_MFW_HDR *) win)->data;
1817 tShowInfo* data = (tShowInfo*) win_data->user;
1818
1819 /* SPR#1428 - SH - New editor changes */
1820 #ifdef NEW_EDITOR
1821 AUI_edit_SetDefault(&data->editor_data);
1822 AUI_edit_SetDisplay(&data->editor_data, NULL, COLOUR_EDITOR, EDITOR_FONT);
1823 AUI_edit_SetTextStr(&data->editor_data, TxtSoftBack, TxtNull, TxtNull, NULL);
1824 AUI_edit_SetEvents(&data->editor_data, 0, TRUE, FOREVER, NULL);
1825 AUI_edit_SetBuffer(&data->editor_data, ATB_DCS_ASCII, (UBYTE *)data->buffer, 35);
1826 AUI_edit_SetMode(&data->editor_data, ED_MODE_READONLY, ED_CURSOR_NONE);
1827 #else /* NEW_EDITOR */
1828 editor_attr_init(&((data->editor_data).editor_attr), NULL, edtCurNone, 0, (char*)data->buffer, 35, COLOUR_EDITOR);
1829 editor_data_init(&data->editor_data, NULL, TxtSoftBack, TxtNull, 0, 1, READ_ONLY_MODE, FOREVER);
1830
1831 data->editor_data.hide = FALSE;
1832 data->editor_data.Identifier = 0;
1833 data->editor_data.TextString = NULL;
1834 data->editor_data.destroyEditor = TRUE;
1835 #endif /* NEW_EDITOR */
1836 }
1837
1838 static void ShowInfoCB( T_MFW_HND win, USHORT Identifier,UBYTE reason)
1839 {
1840 T_MFW_WIN *win_data = ( (T_MFW_HDR *) win )->data;
1841 tShowInfo*data = (tShowInfo*) win_data->user;
1842
1843
1844 TRACE_FUNCTION("ShowVerionCB()");
1845
1846 switch (reason )
1847 {
1848 case INFO_KCD_LEFT:
1849 case INFO_KCD_HUP:
1850 case INFO_KCD_RIGHT:
1851
1852 default:
1853 showGameInfo_destroy(data->win);
1854 break;
1855 }
1856 }
1857
1858 /*******************************************************************************
1859
1860 $Function: showVersion_destroy
1861
1862 $Description: Destroys the editor
1863
1864 $Returns:
1865
1866 $Arguments:
1867
1868 *******************************************************************************/
1869 void showGameInfo_destroy(MfwHnd own_window)
1870 {
1871 T_MFW_WIN * win_data;
1872
1873 tShowInfo* data = NULL;
1874
1875 if (own_window == NULL)
1876 {
1877 TRACE_EVENT ("Error : showGameInfo_destroy called with NULL Pointer");
1878 return;
1879 }
1880
1881
1882 win_data = ((T_MFW_HDR *)own_window)->data;
1883 if (win_data != NULL)
1884 data = (tShowInfo*)win_data->user;
1885
1886 if (data)
1887 {
1888 TRACE_EVENT ("calc_destroy()");
1889
1890 win_delete (data->win);
1891 // Free Memory
1892 FREE_MEMORY ((void *)data, sizeof (tShowInfo));
1893
1894 }
1895 else
1896 {
1897 TRACE_EVENT ("calc_destroy() called twice");
1898 }
1899 }
1900 #endif
1901