Subversion Repositories Kolibri OS

Rev

Rev 1805 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1805 yogev_ezra 1
//
2
 
3
#include "kosSyst.h"
4
#include "KosFile.h"
5
#include "gfxdef.h"
6
#include "gameWnd.h"
7
#include "mcarray.h"
8
#include "lang.h"
9
 
10
//
11
#define EMPTY_PLACE				0
12
 
13
#define LEVEL_PROGRESS_LEFT		(132+1)
14
#define LEVEL_PROGRESS_TOP		(388+21)
15
#define LEVEL_PROGRESS_HEIGHT	4
16
#define LEVEL_PROGRESS_WIDTH	329
17
#define LEVEL_PROGRESS_COLOUR	0xDF2933
18
 
19
#define BONUS_SOMEBLOCK_TOP		(120+21)
20
#define BONUS_SOMEBLOCK_LEFT	(46+1)
21
#define BONUS_FREEBLOCK_TOP		(163+21)
22
#define BONUS_FREEBLOCK_LEFT	(9+1)
23
#define BONUS_DIAGBLOCK_TOP		(213+21)
24
#define BONUS_DIAGBLOCK_LEFT	(48+1)
25
#define BONUS_PROGRESS_HEIGHT	37
26
#define BONUS_PROGRESS_WIDTH	4
27
 
28
#define LEVEL_SCORE_BASE		50
29
 
30
//
31
CKosBitmap gameFace;
32
CKosBitmap gameBlocks;
33
CKosBitmap gameNumbers;
34
CKosBitmap gameBlocksZ[4];
35
//
36
CFishka *fishki[blocksNum];
37
 
38
//
39
char *gameWndTitle;
40
#if LANG == RUS
4481 hidnplayr 41
char gameWndTitle1[] = "” а ®­ ¦¤св ⥡п :)\0";
42
char gameWndTitle2[] = "Ќг ў®в...\0";
1805 yogev_ezra 43
char gameOverText[] = "„ «миҐ ¤®а®ЈЁ ­Ґв!";
44
#else
4481 hidnplayr 45
char gameWndTitle1[] = "Pharaoh waits for you :)\0";
46
char gameWndTitle2[] = "Well...\0";
1805 yogev_ezra 47
char gameOverText[] = "No further way!";
48
#endif
49
//
50
Word gcx, gcy;
51
//
52
#define mapSize			8
53
//
54
//
55
#define blocksLeft		(134+2)
56
#define blocksTop		(43+22)
57
//
58
#define blockTypesNum	10
59
//
60
Byte gameMap[mapSize * mapSize];
61
// уровень
62
int gameLevel;
63
//
64
int maxGameLevel;
65
int startGameLevel;
66
// счёт
67
Dword playerScore;
68
// счётчик добавленных блоков
69
int insertedBlocksCount;
70
// количество блоков для перехода на следующий уровень
71
int levelBlocksLimit;
72
// номер выделенного блока
73
int selectedBlock;
74
// прибавление шага для индикатора прохождения уровня * 1024
75
int levelProgressStep;
76
// занчение индикатора прохождения уровня
77
int levelProgressCount;
78
// блоки для удаления
79
struct sRemoveBlock
80
{
81
	short int ndx;
82
	short int value;
83
	sRemoveBlock()
84
	{
85
		this->ndx = 0;
86
		this->value = 0;
87
	};
88
	sRemoveBlock( int pNdx, int pValue )
89
	{
90
		this->ndx = pNdx;
91
		this->value = pValue;
92
	};
93
};
94
bool operator == ( const sRemoveBlock &b1, const sRemoveBlock &b2 )
95
{
96
	return b1.ndx == b2.ndx;
97
};
98
MCArray toRemoveList;
99
// падающие блоки
100
MCArray toFallList;
101
//
102
bool mouseButtonDisabled;
103
//
104
bool freezeBonuses = false;
105
//
106
int bonusSomeBlockProgressStep;
107
int bonusSomeBlockProgressCount;
108
//
109
int bonusFreeBlockProgressStep;
110
int bonusFreeBlockProgressCount;
111
//
112
int bonusDiagBlockProgressStep;
113
int bonusDiagBlockProgressCount;
114
 
115
 
116
 
117
#define SELECTED_BLOCK_NONE			-1
118
 
119
// бонус включен
120
int bonusSomeBlock;
121
// счётчик блоков для бонуса
122
int bonusSomeBlockCount;
123
// количество блоков, которое надо убрать, чтобы получить бонус
124
int bonusSomeBlockEdge;
125
#define BONUS_SOMEBLOCK_SELECTED	-2
126
//
127
bool bonusFreeBlock;
128
int bonusFreeBlockCount;
129
int bonusFreeBlockEdge;
130
#define BONUS_FREEBLOCK_SELECTED	-3
131
//
132
int bonusDiagBlock;
133
int bonusDiagBlockCount;
134
int bonusDiagBlockEdge;
135
#define BONUS_DIAGBLOCK_SELECTED	-4
136
//
137
void drawScore();
138
// отобразить блоки бонусов
139
void drawBonuses();
140
//
141
void drawLevelNum();
142
//
143
void fadeOutBlocks();
144
//
145
void fallDownBlocks();
146
 
147
 
148
void ClearGameMeters()
149
{
150
	// индикатор прохождение уровня
151
	kos_DrawBar(
152
		LEVEL_PROGRESS_LEFT,
153
		LEVEL_PROGRESS_TOP,
154
		LEVEL_PROGRESS_WIDTH,
155
		LEVEL_PROGRESS_HEIGHT,
156
 
157
		);
158
	// индикаторы бонусов
159
	// some
160
	kos_DrawBar(
161
		33+1,
162
		118+21,
163
		BONUS_PROGRESS_WIDTH,
164
		BONUS_PROGRESS_HEIGHT,
165
 
166
		);
167
	// free
168
	kos_DrawBar(
169
		58+1,
170
		166+21,
171
		BONUS_PROGRESS_WIDTH,
172
		BONUS_PROGRESS_HEIGHT,
173
 
174
		);
175
	// diag
176
	kos_DrawBar(
177
		37+1,
178
		213+21,
179
		BONUS_PROGRESS_WIDTH,
180
		BONUS_PROGRESS_HEIGHT,
181
 
182
		);
183
}
184
 
185
 
186
//
187
void drawGameMeters()
188
{
189
	//
190
	ClearGameMeters();
191
	// индикатор прохождение уровня
192
	kos_DrawBar(
193
		LEVEL_PROGRESS_LEFT,
194
		LEVEL_PROGRESS_TOP,
195
		levelProgressCount,
196
		LEVEL_PROGRESS_HEIGHT,
197
		LEVEL_PROGRESS_COLOUR
198
		);
199
	//
200
	if ( bonusSomeBlockProgressCount > 0 )
201
	// some
202
	kos_DrawBar(
203
		33+1,
204
		118+21+BONUS_PROGRESS_HEIGHT-bonusSomeBlockProgressCount,
205
		BONUS_PROGRESS_WIDTH,
206
		bonusSomeBlockProgressCount,
207
		LEVEL_PROGRESS_COLOUR
208
		);
209
	//
210
	if ( bonusFreeBlockProgressCount > 0 )
211
	// free
212
	kos_DrawBar(
213
		58+1,
214
		166+21+BONUS_PROGRESS_HEIGHT-bonusFreeBlockProgressCount,
215
		BONUS_PROGRESS_WIDTH,
216
		bonusFreeBlockProgressCount,
217
		LEVEL_PROGRESS_COLOUR
218
		);
219
	//
220
	if ( bonusDiagBlockProgressCount > 0 )
221
	// diag
222
	kos_DrawBar(
223
		37+1,
224
		213+21+BONUS_PROGRESS_HEIGHT-bonusDiagBlockProgressCount,
225
		BONUS_PROGRESS_WIDTH,
226
		bonusDiagBlockProgressCount,
227
		LEVEL_PROGRESS_COLOUR
228
		);
229
}
230
 
231
 
232
////////////////////////////////////////////////////////////////////////////////
233
void SetLevelVariables()
234
{
235
	selectedBlock = -1;
236
	levelBlocksLimit = ( gameLevel > 5 ) ? LEVEL_SCORE_BASE * ( gameLevel + 1 ) : LEVEL_SCORE_BASE * ( 11 - gameLevel );
237
	insertedBlocksCount = 0;
238
	//
239
	levelProgressCount = 0;
240
	levelProgressStep = ( LEVEL_PROGRESS_WIDTH * 1024 ) / levelBlocksLimit;
241
	//
242
	bonusSomeBlockEdge = levelBlocksLimit / 4;
243
	bonusFreeBlockEdge = levelBlocksLimit / 3;
244
	bonusDiagBlockEdge = levelBlocksLimit / 2;
245
	//
246
	bonusSomeBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusSomeBlockEdge;
247
	bonusSomeBlockProgressCount = ( ( ( bonusSomeBlockCount > bonusSomeBlockEdge ) ? bonusSomeBlockEdge : bonusSomeBlockCount ) * bonusSomeBlockProgressStep ) / 1024;
248
	//
249
	bonusFreeBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusFreeBlockEdge;
250
	bonusFreeBlockProgressCount = ( ( ( bonusFreeBlockCount > bonusFreeBlockEdge ) ? bonusFreeBlockEdge : bonusFreeBlockCount ) * bonusFreeBlockProgressStep ) / 1024;
251
	//
252
	bonusDiagBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusDiagBlockEdge;
253
	bonusDiagBlockProgressCount = ( ( ( bonusDiagBlockCount > bonusDiagBlockEdge ) ? bonusDiagBlockEdge : bonusDiagBlockCount ) * bonusDiagBlockProgressStep ) / 1024;
254
}
255
 
256
 
257
//
258
int GetScoreByBlocks( int blocksCount )
259
{
260
	int limit, update, i, j, acc;
261
 
262
	//
263
	if ( blocksCount < 3 ) return 0;
264
	//
265
	limit = 20 * blocksNum * gameLevel;
266
	//
267
	update = gameLevel;
268
	acc = 1;
269
	//
270
	j = blocksCount - 3;
271
	//
272
	for ( i = 0; i < j; i++ )
273
	{
274
		//
275
		acc *= gameLevel + 1;
276
		//
277
		if ( ( update + acc ) > limit ) return limit;
278
	}
279
	//
280
	return update + acc;
281
}
282
 
283
 
284
 
285
//
286
int insertNewBlocks()
287
{
288
	int i, j, k, ndx, result, btn;
289
 
290
	//
291
	toFallList.Clear();
292
	//
293
	result = 0;
294
	//
295
	btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel;
296
	//
297
	ndx = ( mapSize * mapSize ) - mapSize;
298
	//
299
	for ( i = 0; i < mapSize; i++ )
300
	{
301
		for ( j = 0; j < mapSize; j++ )
302
		{
303
			//
304
			k = ndx + i - ( j * mapSize );
305
			//
306
			if ( gameMap[k] == EMPTY_PLACE )
307
			{
308
				//
309
				for ( ; j < (mapSize-1); j++ )
310
				{
311
					//
312
					gameMap[k] = gameMap[k-mapSize];
313
					toFallList.AddExclusive( k );
314
					k -= mapSize;
315
				}
316
				//
317
				gameMap[i] = ( rtlRand() % btn ) + 1;
318
				toFallList.AddExclusive( i );
319
				//
320
				result++;
321
				//
322
				break;
323
			}
324
		}
325
	}
326
	//
327
	insertedBlocksCount += result;
328
	//
329
	return result;
330
}
331
 
332
 
333
// поиск цепочек блоков для удаления, удаление блоков
334
// возвращает приращение счёта игрока
335
int findBlockLines()
336
{
337
	int x, y, ndx;
338
	int removeCount = 0;
339
 
340
	// очистим список для записи результатов
341
	toRemoveList.Clear();
342
	//
343
	for ( y = 0; y < mapSize; y++ )
344
	{
345
		//
346
		for ( x = 0; x < mapSize; x++ )
347
		{
348
			//
349
			ndx = x + ( y * mapSize );
350
			//
351
			if ( gameMap[ndx] == EMPTY_PLACE ) continue;
352
			// проверяем горизонтальную цепочку
353
			if ( x < (mapSize - 2) )
354
			{
355
				//
356
				if (
357
					( gameMap[ndx] == gameMap[ndx+1]  &&  gameMap[ndx] == gameMap[ndx+2] )
358
					|| ( BONUS_FREE_BLOCK == gameMap[ndx]  &&  gameMap[ndx+1] == gameMap[ndx+2] )
359
					|| ( gameMap[ndx] == gameMap[ndx+1]  &&  BONUS_FREE_BLOCK == gameMap[ndx+2] )
360
					|| ( gameMap[ndx] == gameMap[ndx+2]  &&  BONUS_FREE_BLOCK == gameMap[ndx+1] )
361
					)
362
				{
363
					// нашли цепочку, запомним
364
					toRemoveList.AddExclusive( sRemoveBlock( ndx, gameMap[ndx] ) );
365
					toRemoveList.AddExclusive( sRemoveBlock( ndx+1, gameMap[ndx+1] ) );
366
					toRemoveList.AddExclusive( sRemoveBlock( ndx+2, gameMap[ndx+2] ) );
367
				}
368
			}
369
			// проверяем вертикальную цепочку
370
			if ( y < (mapSize - 2) )
371
			{
372
				//
373
				if (
374
					( gameMap[ndx] == gameMap[ndx+mapSize]  &&  gameMap[ndx] == gameMap[ndx+mapSize+mapSize] )
375
					|| ( BONUS_FREE_BLOCK == gameMap[ndx]  &&  gameMap[ndx+mapSize] == gameMap[ndx+mapSize+mapSize] )
376
					|| ( gameMap[ndx] == gameMap[ndx+mapSize]  &&  BONUS_FREE_BLOCK == gameMap[ndx+mapSize+mapSize] )
377
					|| ( gameMap[ndx] == gameMap[ndx+mapSize+mapSize]  &&  BONUS_FREE_BLOCK == gameMap[ndx+mapSize] )
378
					)
379
				{
380
					// нашли цепочку, запомним
381
					toRemoveList.AddExclusive( sRemoveBlock( ndx, gameMap[ndx] ) );
382
					toRemoveList.AddExclusive( sRemoveBlock( ndx+mapSize, gameMap[ndx+mapSize] ) );
383
					toRemoveList.AddExclusive( sRemoveBlock( ndx+mapSize+mapSize, gameMap[ndx+mapSize+mapSize] ) );
384
				}
385
			}
386
		}
387
	}
388
	//
389
	return toRemoveList.GetCount();
390
}
391
 
392
 
393
// проверка на невозможность собрать какую-нибудь линию
394
bool checkGameOut()
395
{
396
	int x, y, ndx;
397
 
398
	//
399
	ndx = 0;
400
	//
401
	for ( y = 0; y < mapSize; y++ )
402
	{
403
		//
404
		for ( x = 0; x < mapSize; x++ )
405
		{
406
			// проверяем горизонтальные цепочки из двух символов
407
			if ( x < (mapSize - 1) )
408
			{
409
				//
410
				if ( gameMap[ndx] == gameMap[ndx+1] )
411
				{
412
					// нашли цепочку из двух блоков
413
					// проверка бонусов
414
					if ( bonusSomeBlock == gameMap[ndx] ) return false;
415
					if ( bonusFreeBlock ) return false;
416
					// проверка обычных перестановок
417
					if ( y > 0 )
418
					{
419
						//
420
						if ( x > 0 )
421
						{
422
							//
423
							if ( gameMap[ndx-mapSize-1] == gameMap[ndx] ) return false;
424
						}
425
						//
426
						if ( x < (mapSize - 2) )
427
						{
428
							//
429
							if ( gameMap[ndx-mapSize+2] == gameMap[ndx] ) return false;
430
						}
431
					}
432
					//
433
					if ( x > 1 )
434
					{
435
						//
436
						if ( gameMap[ndx-2] == gameMap[ndx] ) return false;
437
					}
438
					//
439
					if ( x < (mapSize - 3) )
440
					{
441
						//
442
						if ( gameMap[ndx+3] == gameMap[ndx] ) return false;
443
					}
444
					//
445
					if ( y < (mapSize - 1) )
446
					{
447
						//
448
						if ( x > 0 )
449
						{
450
							//
451
							if ( gameMap[ndx+mapSize-1] == gameMap[ndx] ) return false;
452
						}
453
						//
454
						if ( x < (mapSize - 2) )
455
						{
456
							//
457
							if ( gameMap[ndx+mapSize+2] == gameMap[ndx] ) return false;
458
						}
459
					}
460
					// проверка диагональных перестановок
461
					if ( bonusDiagBlock > 0 )
462
					{
463
						//
464
						if ( y > 0 )
465
						{
466
							//
467
							if ( x > 1 )
468
							{
469
								//
470
								if ( gameMap[ndx-mapSize-2] == gameMap[ndx] ) return false;
471
							}
472
							//
473
							if ( gameMap[ndx-mapSize] == gameMap[ndx] ) return false;
474
							//
475
							if ( x < (mapSize - 2) )
476
							{
477
								//
478
								if ( gameMap[ndx-mapSize+1] == gameMap[ndx] ) return false;
479
							}
480
							//
481
							if ( x < (mapSize - 3) )
482
							{
483
								//
484
								if ( gameMap[ndx-mapSize+3] == gameMap[ndx] ) return false;
485
							}
486
						}
487
						//
488
						if ( y < (mapSize - 1) )
489
						{
490
							//
491
							if ( x > 1 )
492
							{
493
								//
494
								if ( gameMap[ndx+mapSize-2] == gameMap[ndx] ) return false;
495
							}
496
							//
497
							if ( gameMap[ndx+mapSize] == gameMap[ndx] ) return false;
498
							//
499
							if ( x < (mapSize - 2) )
500
							{
501
								//
502
								if ( gameMap[ndx+mapSize+1] == gameMap[ndx] ) return false;
503
							}
504
							//
505
							if ( x < (mapSize - 3) )
506
							{
507
								//
508
								if ( gameMap[ndx+mapSize+3] == gameMap[ndx] ) return false;
509
							}
510
						}
511
					} // закончена проверка диагональных перестановок
512
				}
513
			}
514
			// проверяем горизонтальные цепочки из двух блоков с промежутком
515
			if ( x < (mapSize - 2) )
516
			{
517
				//
518
				if ( gameMap[ndx] == gameMap[ndx+2] )
519
				{
520
					// нашли два блока с промежутком
521
					// проверка бонусов
522
					if ( bonusSomeBlock == gameMap[ndx] ) return false;
523
					if ( bonusFreeBlock ) return false;
524
					//
525
					if ( y > 0 )
526
					{
527
						//
528
						if ( gameMap[ndx-mapSize+1] == gameMap[ndx] ) return false;
529
					}
530
					//
531
					if ( y < (mapSize-1) )
532
					{
533
						//
534
						if ( gameMap[ndx+mapSize+1] == gameMap[ndx] ) return false;
535
					}
536
					// проверка диагональных перестановок
537
					if ( bonusDiagBlock > 0 )
538
					{
539
						//
540
						if ( y > 0 )
541
						{
542
							//
543
							if ( gameMap[ndx-mapSize] == gameMap[ndx] ) return false;
544
							//
545
							if ( gameMap[ndx-mapSize+2] == gameMap[ndx] ) return false;
546
						}
547
						//
548
						if ( y < (mapSize-1) )
549
						{
550
							//
551
							if ( gameMap[ndx+mapSize] == gameMap[ndx] ) return false;
552
							//
553
							if ( gameMap[ndx+mapSize+2] == gameMap[ndx] ) return false;
554
						}
555
					}
556
				}
557
			}
558
			// проверяем вертикальные цепочки из двух символов
559
			if ( y < (mapSize - 1) )
560
			{
561
				//
562
				if ( gameMap[ndx] == gameMap[ndx+mapSize] )
563
				{
564
					// нашли цепочку из двух блоков
565
					// проверка бонусов
566
					if ( bonusSomeBlock == gameMap[ndx] ) return false;
567
					if ( bonusFreeBlock ) return false;
568
					//
569
					if ( x > 0 )
570
					{
571
						//
572
						if ( y > 0 )
573
						{
574
							//
575
							if ( gameMap[ndx-1-mapSize] == gameMap[ndx] ) return false;
576
						}
577
						//
578
						if ( y < (mapSize - 2) )
579
						{
580
							//
581
							if ( gameMap[ndx-1+(2*mapSize)] == gameMap[ndx] ) return false;
582
						}
583
					}
584
					//
585
					if ( y > 1 )
586
					{
587
						//
588
						if ( gameMap[ndx-(2*mapSize)] == gameMap[ndx] ) return false;
589
					}
590
					//
591
					if ( y < (mapSize - 3) )
592
					{
593
						//
594
						if ( gameMap[ndx+(3*mapSize)] == gameMap[ndx] ) return false;
595
					}
596
					//
597
					if ( x < (mapSize - 1) )
598
					{
599
						//
600
						if ( y > 0 )
601
						{
602
							//
603
							if ( gameMap[ndx+1-mapSize] == gameMap[ndx] ) return false;
604
						}
605
						//
606
						if ( y < (mapSize - 2) )
607
						{
608
							//
609
							if ( gameMap[ndx+1+(2*mapSize)] == gameMap[ndx] ) return false;
610
						}
611
					}
612
					// проверка диагональных перестановок
613
					if ( bonusDiagBlock > 0 )
614
					{
615
						//
616
						if ( x > 0 )
617
						{
618
							//
619
							if ( y > 1 )
620
							{
621
								//
622
								if ( gameMap[ndx-1-(2*mapSize)] == gameMap[ndx] ) return false;
623
							}
624
							//
625
							if ( gameMap[ndx-1] == gameMap[ndx] ) return false;
626
							//
627
							if ( y < (mapSize - 2) )
628
							{
629
								//
630
								if ( gameMap[ndx-1+mapSize] == gameMap[ndx] ) return false;
631
							}
632
							//
633
							if ( y < (mapSize - 3) )
634
							{
635
								//
636
								if ( gameMap[ndx-1+(3*mapSize)] == gameMap[ndx] ) return false;
637
							}
638
						}
639
						//
640
						if ( x < (mapSize - 1) )
641
						{
642
							//
643
							if ( y > 1 )
644
							{
645
								//
646
								if ( gameMap[ndx+1-(2*mapSize)] == gameMap[ndx] ) return false;
647
							}
648
							//
649
							if ( gameMap[ndx+1] == gameMap[ndx] ) return false;
650
							//
651
							if ( y < (mapSize - 2) )
652
							{
653
								//
654
								if ( gameMap[ndx+1+mapSize] == gameMap[ndx] ) return false;
655
							}
656
							//
657
							if ( y < (mapSize - 3) )
658
							{
659
								//
660
								if ( gameMap[ndx+1+(3*mapSize)] == gameMap[ndx] ) return false;
661
							}
662
						}
663
					} // закончена проверка диагональных перестановок
664
				}
665
			}
666
			// проверяем вертикальные цепочки из двух блоков с промежутком
667
			if ( y < (mapSize - 2) )
668
			{
669
				//
670
				if ( gameMap[ndx] == gameMap[ndx+(2*mapSize)] )
671
				{
672
					// нашли два блока с промежутком
673
					// проверка бонусов
674
					if ( bonusSomeBlock == gameMap[ndx] ) return false;
675
					if ( bonusFreeBlock ) return false;
676
					//
677
					if ( x > 0 )
678
					{
679
						//
680
						if ( gameMap[ndx-1+mapSize] == gameMap[ndx] ) return false;
681
					}
682
					//
683
					if ( x < (mapSize-1) )
684
					{
685
						//
686
						if ( gameMap[ndx+1+mapSize] == gameMap[ndx] ) return false;
687
					}
688
					// проверка диагональных перестановок
689
					if ( bonusDiagBlock > 0 )
690
					{
691
						//
692
						if ( x > 0 )
693
						{
694
							//
695
							if ( gameMap[ndx-1] == gameMap[ndx] ) return false;
696
							//
697
							if ( gameMap[ndx-1+(2*mapSize)] == gameMap[ndx] ) return false;
698
						}
699
						//
700
						if ( x < (mapSize-1) )
701
						{
702
							//
703
							if ( gameMap[ndx+1] == gameMap[ndx] ) return false;
704
							//
705
							if ( gameMap[ndx+1+(2*mapSize)] == gameMap[ndx] ) return false;
706
						}
707
					}
708
				}
709
			}
710
			//
711
			ndx++;
712
		}
713
	}
714
	//
715
	gameWndTitle = gameWndTitle2;
716
	//
717
	return true;
718
}
719
 
720
 
721
//
722
bool exterminateLines()
723
{
724
	int deletedBlocks, btn, i, j;
725
	bool needRedrawBonus = false;
726
 
727
	//
728
	btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel;
729
	//
730
	playerScore += GetScoreByBlocks( deletedBlocks = findBlockLines() );
731
	//
732
	if ( ! freezeBonuses )
733
	{
734
		//
735
		if ( gameLevel >= 2 && bonusSomeBlock <= 0 ) bonusSomeBlockCount += deletedBlocks;
736
		if ( gameLevel >= 3 && !bonusFreeBlock ) bonusFreeBlockCount += deletedBlocks;
737
		if ( gameLevel >= 4 && bonusDiagBlock <= 0 ) bonusDiagBlockCount += deletedBlocks;
738
		// первый бонус
739
		if (
740
			( bonusSomeBlockCount >= bonusSomeBlockEdge || ( gameLevel >= 2 && deletedBlocks >= 4 ) )
741
			&& bonusSomeBlock <= 0
742
			)
743
		{
744
			bonusSomeBlock = ( rtlRand() % btn ) + 1;
745
			needRedrawBonus = true;
746
			if ( bonusSomeBlockCount >= bonusSomeBlockEdge ) bonusSomeBlockCount = 0;
747
		}
748
		if ( bonusSomeBlockCount >= bonusSomeBlockEdge ) bonusSomeBlockCount = 0;
749
		// второй бонус
750
		if ( bonusFreeBlockCount >= bonusFreeBlockEdge || ( gameLevel >=3 && deletedBlocks >= 5 ) )
751
		{
752
			bonusFreeBlock = true;
753
			needRedrawBonus = true;
754
			if ( bonusFreeBlockCount >= bonusFreeBlockEdge ) bonusFreeBlockCount = 0;
755
		}
756
		if ( bonusFreeBlockCount >= bonusFreeBlockEdge ) bonusFreeBlockCount = 0;
757
		// третий бонус
758
		if ( bonusDiagBlockCount >= bonusDiagBlockEdge || ( gameLevel >= 4 && deletedBlocks >= 6 ) )
759
		{
760
			bonusDiagBlock = 3;
761
			needRedrawBonus = true;
762
			if ( bonusDiagBlockCount >= bonusDiagBlockEdge ) bonusDiagBlockCount = 0;
763
		}
764
		if ( bonusDiagBlockCount >= bonusDiagBlockEdge ) bonusDiagBlockCount = 0;
765
		//
766
		bonusSomeBlockProgressCount = ( ( ( bonusSomeBlockCount > bonusSomeBlockEdge ) ? bonusSomeBlockEdge : bonusSomeBlockCount ) * bonusSomeBlockProgressStep ) / 1024;
767
		//
768
		bonusFreeBlockProgressCount = ( ( ( bonusFreeBlockCount > bonusFreeBlockEdge ) ? bonusFreeBlockEdge : bonusFreeBlockCount ) * bonusFreeBlockProgressStep ) / 1024;
769
		//
770
		bonusDiagBlockProgressCount = ( ( ( bonusDiagBlockCount > bonusDiagBlockEdge ) ? bonusDiagBlockEdge : bonusDiagBlockCount ) * bonusDiagBlockProgressStep ) / 1024;
771
		//
772
		if ( needRedrawBonus ) drawBonuses();
773
	}
774
	//
775
	j = toRemoveList.GetCount();
776
	//
777
	for ( i = 0; i < j; i++ )
778
	{
779
		gameMap[toRemoveList[i].ndx] = EMPTY_PLACE;
780
	}
781
	//
782
	return toRemoveList.GetCount() > 0;
783
}
784
 
785
 
786
// заполнение игрового поля случайной комбинацией блоков
787
void initGameMap()
788
{
789
	int i, localScore, localInserted, btn;
790
 
791
	//
792
	btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel;
793
	//
794
	for ( i = 0; i < (mapSize * mapSize); i++ )
795
	{
796
		gameMap[i] = ( rtlRand() % btn ) + 1;
797
	}
798
	//
799
	localScore = playerScore;
800
	localInserted = insertedBlocksCount;
801
	//
802
	freezeBonuses = true;
803
	//
804
	while ( exterminateLines() )
805
	{
806
		while ( insertNewBlocks() > 0 );
807
	}
808
	//
809
	freezeBonuses = false;
810
	//
811
	playerScore = localScore;
812
	insertedBlocksCount = localInserted;
813
}
814
 
815
 
816
// отобразить блоки бонусов
817
void drawBonuses()
818
{
819
	//
820
	kos_PutImage(
821
		selectedBlock != BONUS_SOMEBLOCK_SELECTED ?
822
			fishki[bonusSomeBlock]->GetBits() :
823
			fishki[bonusSomeBlock]->GetHighlightedBits(),
824
		blockSize, blockSize,
825
		BONUS_SOMEBLOCK_LEFT, BONUS_SOMEBLOCK_TOP
826
		);
827
	//
828
	kos_PutImage(
829
		bonusFreeBlock ?
830
		(
831
			selectedBlock != BONUS_FREEBLOCK_SELECTED ?
832
			fishki[BONUS_FREE_BLOCK]->GetBits() :
833
			fishki[BONUS_FREE_BLOCK]->GetHighlightedBits()
834
		) :
835
		fishki[0]->GetBits(),
836
		blockSize, blockSize,
837
		BONUS_FREEBLOCK_LEFT, BONUS_FREEBLOCK_TOP
838
		);
839
	//
840
	kos_PutImage(
841
		bonusDiagBlock > 0 ?
842
			fishki[bonusDiagBlock+BONUS_DIAG_BLOCK-1]->GetBits() :
843
			fishki[0]->GetBits(),
844
		blockSize, blockSize,
845
		BONUS_DIAGBLOCK_LEFT, BONUS_DIAGBLOCK_TOP
846
		);
847
}
848
 
849
 
850
// отобразить игровое поле
851
void drawGameMap()
852
{
853
	int i, j, ndx;
854
 
855
	//
856
	for ( i = 0; i < mapSize; i++ )
857
	{
858
		//
859
		for ( j = 0; j < mapSize; j++ )
860
		{
861
			//
862
			ndx = (i*mapSize) + j;
863
			//
864
			kos_PutImage(
865
				ndx != selectedBlock ?
866
					fishki[gameMap[ndx]]->GetBits() :
867
					fishki[gameMap[ndx]]->GetHighlightedBits(),
868
				blockSize, blockSize,
869
				(j * blockSize) + blocksLeft,
870
				(i * blockSize) + blocksTop
871
				);
872
		}
873
	}
874
}
875
 
876
 
877
// координаты курсора "мыши"
878
int mX, mY;
879
 
880
// проверка на нажатие левой кнопки "мыши"
881
bool mouseLButtonDown()
882
{
883
	static bool isDown = false;
884
	Dword buttons;
885
 
886
	//
887
	kos_GetMouseState( buttons, mX, mY );
888
	//
889
	if ( mouseButtonDisabled ) return false;
890
	//
891
	if ( ( buttons & 1 ) )
892
	{
893
		if ( isDown )
894
			return false;
895
		else
896
		{
897
			isDown = true;
898
			return true;
899
		}
900
	}
901
	else
902
	{
903
		if ( isDown )
904
		{
905
			isDown = false;
906
		}
907
		return false;
908
	}
909
}
910
 
911
//
912
void flipTwoBlocks( int ndx1, int ndx2 )
913
{
914
	Word blX, blY, selX, selY;
915
	Byte fishCode;
916
 
917
	//
918
	blX = ( ndx1 % mapSize ) * blockSize + blocksLeft;
919
	blY = ( ndx1 / mapSize ) * blockSize + blocksTop;
920
	selX = ( ndx2 % mapSize ) * blockSize + blocksLeft;
921
	selY = ( ndx2 / mapSize ) * blockSize + blocksTop;
922
	// переставим блоки местами
923
	fishCode = gameMap[ndx1];
924
	gameMap[ndx1] = gameMap[ndx2];
925
	gameMap[ndx2] = fishCode;
926
	// изображение блока
927
	kos_PutImage(
928
		fishki[gameMap[ndx1]]->GetBits(),
929
		blockSize, blockSize,
930
		blX,
931
		blY
932
		);
933
	// изображение блока
934
	kos_PutImage(
935
		fishki[gameMap[ndx2]]->GetBits(),
936
		blockSize, blockSize,
937
		selX,
938
		selY
939
		);
940
}
941
 
942
 
943
// игровой процесс
944
int GameLoop()
945
{
946
	int result, ndx, blX, blY, selX, selY, ddX, ddY, nSel;
947
	Byte keyCode, mCode;
948
	bool needDecBonus;
949
	Dword buttonID;
950
 
951
	//
952
	gameWndTitle = gameWndTitle1;
953
	gameFace.GetSize( gcx, gcy );
954
	gameLevel = startGameLevel;
955
	playerScore = 0;
956
	bonusSomeBlock = 0;
957
	bonusFreeBlock = false;
958
	bonusDiagBlock = 0;
959
	bonusSomeBlockCount = 0;
960
	bonusFreeBlockCount = 0;
961
	bonusDiagBlockCount = 0;
962
	bonusSomeBlockProgressCount = 0;
963
	bonusFreeBlockProgressCount = 0;
964
	bonusDiagBlockProgressCount = 0;
965
	SetLevelVariables();
966
	mouseButtonDisabled = false;
967
	initGameMap();
968
	//
969
	kos_ChangeWindow( -1, -1, gcx + 1, gcy + 21 );
970
	//
971
	for ( result = GM_NONE; result == GM_NONE; )
972
	{
973
		switch( kos_WaitForEvent() )
974
		{
975
		// надо полностью перерисовать окно
976
		case 1:
977
			DrawGameWindow();
978
			break;
979
 
980
		// клавиатура
981
		case 2:
982
			if ( kos_GetKey( keyCode ) )
983
			{
984
				//
985
				switch ( keyCode )
986
				{
987
				case 0x1B:
988
					result = GM_ABORT;
989
					break;
990
 
991
				default:
992
					break;
993
				}
994
			}
995
			break;
996
 
997
		// кнопки
998
		case 3:
999
			if ( kos_GetButtonID( buttonID ) )
1000
			{
1001
				switch ( buttonID )
1002
				{
1003
				case 0xA:
1004
					result = GM_ABORT;
1005
					break;
1006
 
1007
				default:
1008
					break;
1009
				}
1010
			}
1011
 
1012
		// событие от мыши
1013
		case 6:
1014
			// нажатие левой кнопки?
1015
			if ( mouseLButtonDown() )
1016
			{
1017
				// считаем координаты относително игрового поля
1018
				blX = mX - blocksLeft;
1019
				blY = mY - blocksTop;
1020
				// попало в игровое поле?
1021
				if ( blX >= 0 && blX < (mapSize * blockSize)
1022
					&& blY >= 0 && blY < (mapSize * blockSize) )
1023
				{
1024
					// получаем координаты в блоках
1025
					blX /= blockSize;
1026
					blY /= blockSize;
1027
					// получаем номер блока на карте
1028
					ndx = blX + ( blY * mapSize );
1029
					// ещё одна проверка, чтобы не вылезти за пределы карты
1030
					if ( ndx >= 0 && ndx < (mapSize * mapSize) )
1031
					{
1032
						// начинаем перерисовку
1033
						kos_WindowRedrawStatus( WRS_BEGIN );
1034
						// если не было выбранного блока
1035
						if ( selectedBlock == SELECTED_BLOCK_NONE )
1036
						{
1037
							// запомним выделенный блок
1038
							selectedBlock = ndx;
1039
							// отметим блок на игровом поле
1040
							kos_PutImage(
1041
								fishki[gameMap[selectedBlock]]->GetHighlightedBits(),
1042
								blockSize, blockSize,
1043
								( selectedBlock % mapSize ) * blockSize + blocksLeft,
1044
								( selectedBlock / mapSize ) * blockSize + blocksTop
1045
								);
1046
						}
1047
						else // помеченный блок уже есть
1048
						{
1049
							if ( selectedBlock >= 0 )
1050
							{
1051
								// координаты помеченного блока
1052
								selX = selectedBlock % mapSize;
1053
								selY = selectedBlock / mapSize;
1054
								// был выбран другой блок?
1055
								if ( ndx != selectedBlock )
1056
								{
1057
									// считаем разность координат двух блоков
1058
									ddX = selX - blX;
1059
									ddY = selY - blY;
1060
									needDecBonus = ( bonusDiagBlock > 0 && abs(ddX) == 1 && abs(ddY) == 1 );
1061
									// если это соседний блок
1062
									if (
1063
										( abs(ddX) == 1 && ddY == 0 )
1064
										|| ( abs(ddY) == 1 && ddX == 0 )
1065
										|| needDecBonus
1066
										)
1067
									{
1068
										// переставим блоки местами
1069
										flipTwoBlocks( ndx, selectedBlock );
1070
										//
1071
										kos_Pause( 16 );
1072
										//
1073
										if ( findBlockLines() > 0 )
1074
										{
1075
											//
1076
											if ( needDecBonus )
1077
											{
1078
												//
1079
												--bonusDiagBlock;
1080
												//
1081
												drawBonuses();
1082
											}
1083
											// снимаем пометку с блока
1084
											selectedBlock = SELECTED_BLOCK_NONE;
1085
											//
1086
											while ( exterminateLines() )
1087
											{
1088
												//
1089
												fadeOutBlocks();
1090
												//
1091
												//drawGameMap();
1092
												//drawScore();
1093
												//
1094
												//kos_Pause( 25 );
1095
												//
1096
												while ( insertNewBlocks() > 0 )
1097
												{
1098
													//
1099
													fallDownBlocks();
1100
													//
1101
													//drawGameMap();
1102
													//kos_Pause( 30 );
1103
												}
1104
											}
1105
											//
1106
											drawScore();
1107
											//
1108
											levelProgressCount = ( ( ( insertedBlocksCount > levelBlocksLimit ) ? levelBlocksLimit : insertedBlocksCount ) * levelProgressStep ) / 1024;
1109
											//
1110
											drawGameMeters();
1111
											//
1112
											if ( insertedBlocksCount > levelBlocksLimit )
1113
											{
1114
												kos_Pause( 50 );
1115
												gameLevel++;
1116
												SetLevelVariables();
1117
												//
1118
												//initGameMap();
1119
												//
1120
												//DrawGameWindow();
1121
												//
1122
												drawGameMeters();
1123
												drawLevelNum();
1124
											}
1125
											else
1126
												//
1127
												if ( mouseButtonDisabled = checkGameOut() )
1128
												{
1129
													//
1130
													DrawGameWindow();
1131
												}
1132
										}
1133
										else
1134
										{
1135
											// не получается линии, блоки ставим на место
1136
											flipTwoBlocks( ndx, selectedBlock );
1137
											// снимаем пометку с блока
1138
											selectedBlock = SELECTED_BLOCK_NONE;
1139
										}
1140
									}
1141
									else // выбран несоседний блок
1142
									{
1143
										// перестим маркер
1144
										kos_PutImage(
1145
											fishki[gameMap[selectedBlock]]->GetBits(),
1146
											blockSize, blockSize,
1147
											selX * blockSize + blocksLeft,
1148
											selY * blockSize + blocksTop
1149
											);
1150
										// пометим выбранный блок
1151
										selectedBlock = ndx;
1152
										// на игровом поле
1153
										kos_PutImage(
1154
											fishki[gameMap[selectedBlock]]->GetHighlightedBits(),
1155
											blockSize, blockSize,
1156
											blX * blockSize + blocksLeft,
1157
											blY * blockSize + blocksTop
1158
											);
1159
									}
1160
								}
1161
								else // выбран тот же блок
1162
								{
1163
									// снимаем пометку
1164
									kos_PutImage(
1165
										fishki[gameMap[selectedBlock]]->GetBits(),
1166
										blockSize, blockSize,
1167
										selX * blockSize + blocksLeft,
1168
										selY * blockSize + blocksTop
1169
										);
1170
									//
1171
									selectedBlock = SELECTED_BLOCK_NONE;
1172
								}
1173
							}
1174
							else
1175
							// ткнули в блок при выбранном бонусе
1176
							{
1177
								//
1178
								mCode = gameMap[ndx];
1179
								//
1180
								switch ( selectedBlock )
1181
								{
1182
								case BONUS_SOMEBLOCK_SELECTED:
1183
									gameMap[ndx] = bonusSomeBlock;
1184
									break;
1185
 
1186
								case BONUS_FREEBLOCK_SELECTED:
1187
									gameMap[ndx] = BONUS_FREE_BLOCK;
1188
									break;
1189
 
1190
								default:
1191
									break;
1192
								}
1193
								//
1194
								if ( findBlockLines() > 0 )
1195
								{
1196
									// убираем использованный бонус
1197
									switch ( selectedBlock )
1198
									{
1199
									case BONUS_SOMEBLOCK_SELECTED:
1200
										bonusSomeBlock = 0;
1201
										break;
1202
 
1203
									case BONUS_FREEBLOCK_SELECTED:
1204
										bonusFreeBlock = false;
1205
										break;
1206
 
1207
									default:
1208
										break;
1209
									}
1210
									// на экране тоже
1211
									drawBonuses();
1212
									drawGameMap();
1213
									kos_Pause( 16 );
1214
									// убираем блоки
1215
									// снимаем пометку с блока
1216
									selectedBlock = SELECTED_BLOCK_NONE;
1217
									//
1218
									while ( exterminateLines() )
1219
									{
1220
										//
1221
										fadeOutBlocks();
1222
										//
1223
										//drawGameMap();
1224
										//drawScore();
1225
										//
1226
										//kos_Pause( 25 );
1227
										//
1228
										while ( insertNewBlocks() > 0 )
1229
										{
1230
											//
1231
											fallDownBlocks();
1232
											//
1233
											//drawGameMap();
1234
											//kos_Pause( 30 );
1235
										}
1236
									}
1237
									//
1238
									drawScore();
1239
									//
1240
									levelProgressCount = ( ( ( insertedBlocksCount > levelBlocksLimit ) ? levelBlocksLimit : insertedBlocksCount ) * levelProgressStep ) / 1024;
1241
									//
1242
									drawGameMeters();
1243
									//
1244
									if ( insertedBlocksCount > levelBlocksLimit )
1245
									{
1246
										kos_Pause( 50 );
1247
										gameLevel++;
1248
										SetLevelVariables();
1249
										//
1250
										//initGameMap();
1251
										//
1252
										//DrawGameWindow();
1253
										//
1254
										drawGameMeters();
1255
										drawLevelNum();
1256
									}
1257
									else
1258
										//
1259
										mouseButtonDisabled = checkGameOut();
1260
								}
1261
								else
1262
								// бонус здесь неприменим
1263
								{
1264
									// вернём взад
1265
									gameMap[ndx] = mCode;
1266
									// пометим блок
1267
									selectedBlock = ndx;
1268
									// на игровом поле
1269
									kos_PutImage(
1270
										fishki[gameMap[selectedBlock]]->GetHighlightedBits(),
1271
										blockSize, blockSize,
1272
										blX * blockSize + blocksLeft,
1273
										blY * blockSize + blocksTop
1274
										);
1275
									// уберём пометку с бонуса
1276
									drawBonuses();
1277
								}
1278
							}
1279
						}
1280
						// определим кнопку
1281
						kos_DefineButton(
1282
							444+1, 2+21,
1283
							54, 20,
1284
							0x6000000A,
1285
 
1286
							);
1287
						// завершаем перерисовку
1288
						kos_WindowRedrawStatus( WRS_END );
1289
					}
1290
				}
1291
				else
1292
				// проверим попадание в бонусы
1293
				{
1294
					nSel = 0;
1295
					//
1296
					if ( mX >= BONUS_SOMEBLOCK_LEFT && (mX - BONUS_SOMEBLOCK_LEFT) <= blockSize
1297
						&& mY >= BONUS_SOMEBLOCK_TOP && (mY - BONUS_SOMEBLOCK_TOP ) <= blockSize )
1298
					{
1299
						//
1300
						nSel = BONUS_SOMEBLOCK_SELECTED;
1301
					}
1302
					//
1303
					if ( mX >= BONUS_FREEBLOCK_LEFT && (mX - BONUS_FREEBLOCK_LEFT) <= blockSize
1304
						&& mY >= BONUS_FREEBLOCK_TOP && (mY - BONUS_FREEBLOCK_TOP ) <= blockSize )
1305
					{
1306
						//
1307
						nSel = BONUS_FREEBLOCK_SELECTED;
1308
					}
1309
					//
1310
					if ( mX >= BONUS_DIAGBLOCK_LEFT && (mX - BONUS_DIAGBLOCK_LEFT) <= blockSize
1311
						&& mY >= BONUS_DIAGBLOCK_TOP && (mY - BONUS_DIAGBLOCK_TOP ) <= blockSize )
1312
					{
1313
						//
1314
						nSel = BONUS_DIAGBLOCK_SELECTED;
1315
					}
1316
					//
1317
					if ( nSel != 0 )
1318
					{
1319
						//
1320
						if ( selectedBlock > 0 )
1321
						{
1322
							// снимаем пометку
1323
							kos_PutImage(
1324
								fishki[gameMap[selectedBlock]]->GetBits(),
1325
								blockSize, blockSize,
1326
								(selectedBlock % mapSize) * blockSize + blocksLeft,
1327
								(selectedBlock / mapSize) * blockSize + blocksTop
1328
								);
1329
						}
1330
						//
1331
						if ( selectedBlock != nSel )
1332
							selectedBlock = nSel;
1333
						else
1334
							selectedBlock = SELECTED_BLOCK_NONE;
1335
						//
1336
						drawBonuses();
1337
					}
1338
				}
1339
 
1340
			}
1341
			//
1342
			break;
1343
 
1344
		default:
1345
			break;
1346
		}
1347
	}
1348
	// отменим кнопку
1349
	kos_DefineButton(
1350
		0, 0,
1351
		0, 0,
1352
		0x8000000A,
1353
 
1354
		);
1355
	//
1356
	if ( gameLevel > maxGameLevel ) maxGameLevel = gameLevel;
1357
	//
1358
	return result;
1359
}
1360
 
1361
//
1362
void drawLevelNum()
1363
{
1364
	Word startX;
1365
 
1366
	//
1367
	if ( gameLevel > 9 )
1368
	{
1369
		//
1370
		startX = LEVEL_LEFT;
1371
		//
1372
		kos_PutImage(
1373
			gameNumbers.GetBits() + ( ( gameLevel / 10 ) * NUM_WIDTH * NUM_HEIGHT ),
1374
			NUM_WIDTH, NUM_HEIGHT,
1375
			startX, LEVEL_TOP
1376
			);
1377
		//
1378
		startX += NUM_WIDTH;
1379
	}
1380
	else
1381
	{
1382
		//
1383
		startX = LEVEL_LEFT + ( (LEVEL_WIDTH - NUM_WIDTH) / 2 );
1384
	}
1385
	//
1386
	kos_PutImage(
1387
		gameNumbers.GetBits() + ( ( gameLevel % 10 ) * NUM_WIDTH * NUM_HEIGHT ),
1388
		NUM_WIDTH, NUM_HEIGHT,
1389
		startX, LEVEL_TOP
1390
		);
1391
}
1392
 
1393
//
1394
void drawScore()
1395
{
1396
	Word startX;
1397
	int i, j;
1398
	char strNum[8];
1399
 
1400
	// число в текстовом виде
1401
	sprintf( strNum, "%U", playerScore );
1402
	//
1403
	j = strlen( strNum );
1404
	//
1405
	startX = SCORE_LEFT + ( ( SCORE_WIDTH - ( NUM_WIDTH * j ) ) / 2 );
1406
	//
1407
	for ( i = 0; i < j; i++ )
1408
	{
1409
		//
1410
		kos_PutImage(
1411
			gameNumbers.GetBits() + ( ( strNum[i] - '0' ) * NUM_WIDTH * NUM_HEIGHT ),
1412
			NUM_WIDTH, NUM_HEIGHT,
1413
			startX, SCORE_TOP
1414
			);
1415
		//
1416
		startX += NUM_WIDTH;
1417
	}
1418
}
1419
 
1420
 
1421
//
1422
void DrawGameWindow()
1423
{
1424
	//
1425
	kos_WindowRedrawStatus( WRS_BEGIN );
1426
	// окно
1427
	kos_DefineAndDrawWindow(
1428
		WNDLEFT, WNDTOP,
1429
		gcx + 1, gcy + 21,
4481 hidnplayr 1430
		0x14, 0x0,
1805 yogev_ezra 1431
		0, WNDHEADCOLOUR,
4481 hidnplayr 1432
		gameWndTitle
1805 yogev_ezra 1433
		);
1434
	// заголовок окна
4481 hidnplayr 1435
	  kos_ChangeWindowCaption(gameWndTitle);
1805 yogev_ezra 1436
	gameFace.Draw( 1, 21 );
1437
	drawGameMap();
1438
	drawGameMeters();
1439
	drawBonuses();
1440
	// номер уровня
1441
	drawLevelNum();
1442
	drawScore();
1443
	//
1444
	if ( mouseButtonDisabled )
1445
	{
1446
		//
1447
		kos_DrawBar(
1448
			( gcx + 1 - 160 ) / 2, ( gcy + 21 - 32 ) / 2,
1449
			160, 32,
1450
			0x2383B3
1451
			);
1452
		//
1453
		kos_WriteTextToWindow(
1454
			( gcx + 1 - sizeof( gameOverText ) * 6 ) / 2, ( gcy + 21 - 9 ) / 2,
1455
			0x0, 0xF7F7F7,
1456
			gameOverText,
1457
			sizeof( gameOverText )
1458
			);
1459
	}
1460
	// определим кнопку
1461
	kos_DefineButton(
1462
		444+1, 2+21,
1463
		54, 20,
1464
		0x6000000A,
1465
 
1466
		);
1467
	//
1468
	kos_WindowRedrawStatus( WRS_END );
1469
}
1470
 
1471
 
1472
//
1473
void fadeOutBlocks()
1474
{
1475
	int i, j, k, ndx, x, y;
1476
 
1477
	//
1478
	j = toRemoveList.GetCount();
1479
	//
1480
	for ( k = 0; k < 4; k++ )
1481
	{
1482
		//
1483
		__asm{
1484
				push	eax
1485
				push	ebx
1486
				mov		eax, 18
1487
				mov		ebx, 14
1488
				int		0x40
1489
				pop		eax
1490
				pop		ebx
1491
		}
1492
		//
1493
		for ( i = 0; i < j; i++ )
1494
		{
1495
			//
1496
			ndx = toRemoveList[i].ndx;
1497
			y = ndx / mapSize;
1498
			x = ndx % mapSize;
1499
			//
1500
			kos_PutImage(
1501
				gameBlocksZ[k].GetBits() + ( (toRemoveList[i].value - 1) * blockSize * blockSize ),
1502
				blockSize, blockSize,
1503
				(x * blockSize) + blocksLeft,
1504
				(y * blockSize) + blocksTop
1505
				);
1506
		}
1507
		//
1508
		kos_Pause( 3 );
1509
	}
1510
	//clear
1511
	for ( i = 0; i < j; i++ )
1512
	{
1513
		//
1514
		ndx = toRemoveList[i].ndx;
1515
		y = ndx / mapSize;
1516
		x = ndx % mapSize;
1517
		//
1518
		kos_DrawBar(
1519
			(x * blockSize) + blocksLeft,
1520
			(y * blockSize) + blocksTop,
1521
			blockSize, blockSize, 0
1522
			);
1523
	}
1524
	//
1525
	kos_Pause( 16 );
1526
}
1527
 
1528
 
1529
//
1530
void fallDownBlocks()
1531
{
1532
	int i, j, k, ndx, x, y, height, offset;
1533
 
1534
	//
1535
	j = toFallList.GetCount();
1536
	//
1537
	for ( k = 1; k <= blockSize; k += 2 )
1538
	{
1539
		//
1540
		__asm{
1541
				push	eax
1542
				push	ebx
1543
				mov		eax, 18
1544
				mov		ebx, 14
1545
				int		0x40
1546
				pop		eax
1547
				pop		ebx
1548
		}
1549
		//
1550
		for ( i = 0; i < j; i++ )
1551
		{
1552
			//
1553
			ndx = toFallList[i];
1554
			//
1555
			y = ( ( ( ndx / mapSize ) - 1 ) * blockSize ) + k;
1556
			if ( y < 0 )
1557
			{
1558
				y = 0;
1559
				height = k;
1560
				offset = blockSize - k;
1561
			}
1562
			else
1563
			{
1564
				offset = 0;
1565
				height = blockSize;
1566
			}
1567
			//
1568
			x = ( ndx % mapSize ) * blockSize;
1569
			//
1570
			kos_PutImage(
1571
				fishki[gameMap[ndx]]->GetBits() + ( offset * blockSize ),
1572
				blockSize, height,
1573
				x + blocksLeft,
1574
				y + blocksTop
1575
				);
1576
		}
1577
		//
1578
		kos_Pause( 1 );
1579
	}
1580
}