Subversion Repositories NedoOS

Rev

Details | Last modification | View Log

Rev Author Line No. Line
1694 Urfin 1
#include "../_sdk/evo.h"
2
#include "resources.h"
3
#include "functions.h"
4
#include "intro.h"
5
 
6
#define HIGH_MAP        11      // высота матрицы стакана
7
#define WIDTH_MAP       5       // ширина матрицы стакана
8
 
9
#define LEFT_LIMIT      60      // левая граница стакана
10
#define RIGHT_LIMIT 92  // правая граница стакана
11
#define TOP_LIMIT       16      // верхняя точка стакана
12
#define DOWN_LIMIT      160 // нижняя граница стакана
13
#define X_SCORE         34
14
#define Y_SCORE         7
15
#define X_BESTSCORE     34
16
#define Y_BESTSCORE     17
17
#define X_NEXT          24
18
#define Y_NEXT          56
19
#define X_ROTATE        7
20
#define Y_ROTATE        15
21
 
22
 
23
//структура списка лидеров
24
static struct
25
{
26
        u16 scoreboard;
27
        u8 name[9];
28
}best[8];
29
 
30
 
31
static u16 score=0; // общие набранные очки
32
static u16 rotate=0; // замены кубика
33
static u16 score_rotate=0;
34
static u8 map[HIGH_MAP][WIDTH_MAP]; // матрица игрового поля
35
static u8 gN=0;
36
static u8 yLimit=0;             //расстояние до дна
37
static u8 boxReel=0;    //варианты возможных кубиков
38
static u8 i, j;
39
 
40
 
41
 
42
//структура спрайта
43
static struct
44
{
45
        u16 x,y;        //координаты
46
        u8 variant;     //вид кубика
47
        u8 variantNext; //следующий кубик
48
        u8 str,col;     //координаты кубика в матрице
49
}box;
50
 
51
 
52
 
53
 
54
#include "saveload.h"
55
 
56
// инициализация списка лидеров
57
void BestInit()
58
{
59
        for (i=0;i<8;i++)
60
        {
61
                best[i].scoreboard=0;
62
                for (j=0;j<8;j++)
63
                        best[i].name[j]='.';
64
        }
65
}
66
 
67
 
68
 
69
//stop spacebar
70
void Stop()
71
{
72
        u8 done=FALSE;
73
        while(!done)
74
        {
75
                vsync();
76
                if(joystick()&JOY_FIRE) done=TRUE;
77
        }
78
}
79
 
80
 
81
 
82
// вывод bestscore
83
void put_best_score()
84
{
85
        u16 bestscore=0;
86
 
87
        select_image(IMG_FONT);// выбор изображения для тайлов
88
        color_key(15);
89
 
90
        for (i=0;i<8;i++)
91
                if (best[i].scoreboard>bestscore) bestscore=best[i].scoreboard;
92
 
93
        for (i=0;i<=3;i++)
94
        {
95
                draw_tile(X_BESTSCORE-i,Y_BESTSCORE,16+(bestscore%10));
96
                bestscore/=10;
97
        }
98
}
99
 
100
 
101
 
102
// вывод score и rotate на экран
103
void put_score(u16 score, u16 rotate)
104
{
105
        select_image(IMG_FONT);// выбор изображения для тайлов
106
        color_key(15);
107
 
108
        for (i=0;i<=3;i++)
109
        {
110
                draw_tile(X_SCORE-i,Y_SCORE,16+(score%10));
111
                score/=10;
112
        }
113
        if (rotate==0) draw_image(5,13,IMG_ROTOR_DIS);
114
        else
115
        {
116
                draw_image(5,13,IMG_ROTOR_EN);
117
                for (i=0;i<=1;i++)
118
                {
119
                        draw_tile(X_ROTATE-i,Y_ROTATE,16+(rotate%10));
120
                        rotate/=10;
121
                }
122
        }
123
}
124
 
125
 
126
 
127
 
128
// вывод строк по координатам
129
void put_string(u8 output_x, u8 output_y, u8* str)
130
{
131
        u8 n;
132
        while(1)
133
        {
134
                n=*str++;
135
                if(!n) break;
136
                draw_tile(output_x,output_y,n-' ');
137
                ++output_x;
138
        }
139
}
140
 
141
 
142
 
143
// ввод имени в таблицу лидеров
144
void PutName(u8 output_x, u8 output_y)
145
{
146
        u32 n=time();
147
        u8 key;
148
        u8 keys[40];
149
 
150
        select_image(IMG_FONT);//выбор изображения для вывода тайлов
151
 
152
        while(1)
153
        {
154
                //получение состояния клавиш
155
                keyboard(keys);
156
 
157
                key=255;
158
 
159
                if(keys[KEY_0]&KEY_PRESS) key='0';
160
                if(keys[KEY_1]&KEY_PRESS) key='1';
161
                if(keys[KEY_2]&KEY_PRESS) key='2';
162
                if(keys[KEY_3]&KEY_PRESS) key='3';
163
                if(keys[KEY_4]&KEY_PRESS) key='4';
164
                if(keys[KEY_5]&KEY_PRESS) key='5';
165
                if(keys[KEY_6]&KEY_PRESS) key='6';
166
                if(keys[KEY_7]&KEY_PRESS) key='7';
167
                if(keys[KEY_8]&KEY_PRESS) key='8';
168
                if(keys[KEY_9]&KEY_PRESS) key='9';
169
 
170
                if(keys[KEY_A]&KEY_PRESS) key='A';
171
                if(keys[KEY_B]&KEY_PRESS) key='B';
172
                if(keys[KEY_C]&KEY_PRESS) key='C';
173
                if(keys[KEY_D]&KEY_PRESS) key='D';
174
                if(keys[KEY_E]&KEY_PRESS) key='E';
175
                if(keys[KEY_F]&KEY_PRESS) key='F';
176
                if(keys[KEY_G]&KEY_PRESS) key='G';
177
                if(keys[KEY_H]&KEY_PRESS) key='H';
178
                if(keys[KEY_I]&KEY_PRESS) key='I';
179
                if(keys[KEY_J]&KEY_PRESS) key='J';
180
                if(keys[KEY_K]&KEY_PRESS) key='K';
181
                if(keys[KEY_L]&KEY_PRESS) key='L';
182
                if(keys[KEY_M]&KEY_PRESS) key='M';
183
                if(keys[KEY_N]&KEY_PRESS) key='N';
184
                if(keys[KEY_O]&KEY_PRESS) key='O';
185
                if(keys[KEY_P]&KEY_PRESS) key='P';
186
                if(keys[KEY_Q]&KEY_PRESS) key='Q';
187
                if(keys[KEY_R]&KEY_PRESS) key='R';
188
                if(keys[KEY_S]&KEY_PRESS) key='S';
189
                if(keys[KEY_T]&KEY_PRESS) key='T';
190
                if(keys[KEY_U]&KEY_PRESS) key='U';
191
                if(keys[KEY_V]&KEY_PRESS) key='V';
192
                if(keys[KEY_W]&KEY_PRESS) key='W';
193
                if(keys[KEY_X]&KEY_PRESS) key='X';
194
                if(keys[KEY_Y]&KEY_PRESS) key='Y';
195
                if(keys[KEY_Z]&KEY_PRESS) key='Z';
196
 
197
                if(keys[KEY_SPACE]&KEY_PRESS) key=' ';
198
                if(keys[KEY_ENTER]&KEY_PRESS) key='\n';
199
 
200
                //если была нажата клавиша, вывести ее
201
                if(key!=255)
202
                {
203
                        if(key>=' '&&key<='Z')
204
                        {
205
                                draw_tile(output_x,output_y,key-' ');
206
                        }
207
                        if(output_x==22)
208
                        {
209
                                output_x=21;
210
                        }
211
                        if(key=='\n')
212
                        {
213
                                swap_screen();
214
                                set_sprite(0,output_x*4,output_y*8-5,SPRITE_END);
215
                                swap_screen();
216
                                set_sprite(0,output_x*4,output_y*8-5,SPRITE_END);
217
 
218
                                sprites_stop();
219
 
220
                                return;
221
                        }
222
                        if(key=='0'||joystick()&JOY_LEFT)
223
                        {
224
                                for (i=0;i<8;i++) best[((output_y-5)/2)].name[i]='.';
225
                                put_string (14,output_y,best[((output_y-5)/2)].name);
226
                                output_x=13;
227
                        }
228
                        best[((output_y-5)/2)].name[(output_x-14)]=key;
229
                        output_x++;
230
                        if(output_x==22)
231
                        {
232
                                output_x=21;
233
                        }
234
                }
235
 
236
 
237
                if (n+25>time()) // мигающий курсор
238
                {
239
                        set_sprite(0,output_x*4,output_y*8-5,11);
240
                        swap_screen();
241
                }
242
                else if (n+50>time())
243
                {
244
                        set_sprite(0,output_x*4,output_y*8-5,10);
245
                        swap_screen();
246
                }
247
                else n=time();
248
        }
249
 
250
 
251
}
252
 
253
 
254
 
255
 
256
// конец игры и вывод лучших результатов
257
void GameOver()
258
{
259
        u8 n, m;
260
        u16 b;
261
        u8 output_y=3;
262
        u8 output_yy=5;
263
 
264
 
265
        draw_image(14,11,IMG_GAMEOVER);
266
        swap_screen();
267
 
268
        Stop();
269
 
270
        sprites_stop();
271
        clear_screen(0);
272
        swap_screen();
273
        clear_screen(0);
274
        swap_screen();
275
        sprites_start();
276
        draw_image(0,0,IMG_BEST);
277
 
278
        for (j=0;j<8;j++) //проверка на лидерство
279
        {
280
                if (score>best[j].scoreboard)
281
                {
282
                        for (i=8;i>j;i--)
283
                        {
284
                                best[i].scoreboard=best[i-1].scoreboard;
285
                                for (n=0;n<8;n++) best[i].name[n]=best[i-1].name[n];
286
                        }
287
                        best[j].scoreboard=score;
288
                        for (i=0;i<8;i++) best[j].name[i]='.';
289
                        score=0;
290
                        output_yy+=(2*j);
291
                }
292
        }
293
 
294
        select_image(IMG_FONT);// выбор изображения для шрифта
295
        for (j=0;j<8;j++) // вывод списка лидеров
296
        {
297
                output_y+=2;
298
                b=best[j].scoreboard;
299
                for (i=0;i<=3;i++)
300
                {
301
                        draw_tile(27-i,output_y,16+(b%10));
302
                        b/=10;
303
                }
304
                put_string (14,output_y,best[j].name);
305
        }
306
 
307
        swap_screen();
308
 
309
        if (score==0)PutName(14,output_yy);
310
 
311
 
312
        SaveBest();
313
 
314
        save_to_file("savelist.bin");
315
 
316
        new_exit();
317
}
318
 
319
 
320
 
321
// подготовка игрового экрана
322
void InitScreen()
323
{
324
        //обнуление матрицы стакана
325
        for(i=0;i<HIGH_MAP;++i)
326
                for(j=0;j<WIDTH_MAP;++j) map[i][j]=0;
327
 
328
        // обнуление замен кубика
329
        rotate=0;
330
        score_rotate=0;
331
 
332
        //обнуление вариантов кубика
333
        boxReel=0;
334
 
335
        box.variantNext=0;
336
 
337
        //черный экран на время подготовки
338
        //pal_bright(BRIGHT_MIN);
339
 
340
        //установка палитры
341
        pal_select(PAL_BOX);
342
 
343
        //запуск спрайтов
344
        sprites_start();
345
 
346
        //очистка теневого экрана нужным цветом 0..15
347
        border(0);
348
        clear_screen(0);
349
 
350
        //вывод фона на теневой экран
351
        draw_image(0,0,IMG_BACK);
352
 
353
        //вывод строки очков
354
        put_score(0,0);
355
 
356
        //вывод строки лидера
357
        put_best_score();
358
 
359
        //установка нормальной яркости
360
        pal_bright(BRIGHT_MID);
361
 
362
}
363
 
364
 
365
 
366
// обновление спрайта
367
void Update()
368
{
369
        set_sprite(0,box.x,box.y,box.variant);
370
        set_sprite(1,X_NEXT,Y_NEXT,box.variantNext);
371
        swap_screen();
372
}
373
 
374
 
375
 
376
// отрисовка кубика тайлом
377
void DrawTileBox(u8 str, u8 col, u8 variant)
378
{
379
        select_image(IMG_BOX);  // выбор изображения для тайлов
380
        color_key(15);
381
 
382
        draw_tile_key(15+col*2,2+str*2,4*variant);
383
        draw_tile_key(16+col*2,2+str*2,4*variant+1);
384
        draw_tile_key(15+col*2,3+str*2,4*variant+2);
385
        draw_tile_key(16+col*2,3+str*2,4*variant+3);   
386
 
387
        //set_sprite(0,LEFT_LIMIT+col*8,TOP_LIMIT+str*16,SPRITE_END);
388
        swap_screen();
389
}
390
 
391
 
392
 
393
// инициализация нового кубика
394
void InitNewBox()
395
{
396
        u8 n;
397
 
398
        box.x=LEFT_LIMIT+16;
399
        box.y=TOP_LIMIT;
400
        box.col=2;
401
        box.str=0;
402
        box.variant=box.variantNext;
403
 
404
        n=rand16()%100;
405
        switch (boxReel)
406
        {
407
                case 0: box.variantNext=0;
408
                break;
409
 
410
                case 1:
411
                if (n<30) box.variantNext=0;            // 30%-2  70%-4
412
                else box.variantNext=1;
413
                break;
414
 
415
                case 2:
416
                if (n<40) box.variantNext=0;            // 40%-2  40%-4  20%-8
417
                else if (n<80) box.variantNext=1;
418
                else box.variantNext=2;
419
                break;
420
 
421
                case 3:
422
                if (n<40) box.variantNext=0;            // 40%-2  30%-4  20%-8  10%-16
423
                else if (n<70) box.variantNext=1;
424
                else if (n<90) box.variantNext=2;
425
                else box.variantNext=3;
426
                break;
427
 
428
                case 4:
429
                if (n<30) box.variantNext=0;            // 30%-2  25%-4  20%-8  15%-16  10%-32
430
                else if (n<55) box.variantNext=1;
431
                else if (n<75) box.variantNext=2;
432
                else if (n<90) box.variantNext=3;
433
                else box.variantNext=4;
434
                break;
435
 
436
                case 5:
437
                if (n<30) box.variantNext=0;            // 30%-2  25%-4  20%-8  10%-16  10%-32  5%-64
438
                else if (n<55) box.variantNext=1;
439
                else if (n<75) box.variantNext=2;
440
                else if (n<85) box.variantNext=3;
441
                else if (n<95) box.variantNext=4;
442
                else box.variantNext=5;
443
                break;
444
 
445
                case 6:
446
                if (n<25) box.variantNext=0;            // 25%-2  25%-4  20%-8  10%-16  10%-32  5%-64  5%-128
447
                else if (n<50) box.variantNext=1;
448
                else if (n<70) box.variantNext=2;
449
                else if (n<80) box.variantNext=3;
450
                else if (n<90) box.variantNext=4;
451
                else if (n<95) box.variantNext=5;
452
                else box.variantNext=6;
453
                break;
454
 
455
                case 7:
456
                if (n<20) box.variantNext=0;            // 20%-2  20%-4  20%-8  15%-16  10%-32  10%-64  3%-128  2%-256
457
                else if (n<40) box.variantNext=1;
458
                else if (n<60) box.variantNext=2;
459
                else if (n<75) box.variantNext=3;
460
                else if (n<85) box.variantNext=4;
461
                else if (n<95) box.variantNext=5;
462
                else if (n<98) box.variantNext=6;
463
                else box.variantNext=7;
464
                break;
465
 
466
                case 8:
467
                if (n<20) box.variantNext=0;            // 20%-2  20%-4  20%-8  15%-16  10%-32  5%-64  5%-128  3%-256 2%-512
468
                else if (n<40) box.variantNext=1;
469
                else if (n<60) box.variantNext=2;
470
                else if (n<75) box.variantNext=3;
471
                else if (n<85) box.variantNext=4;
472
                else if (n<90) box.variantNext=5;
473
                else if (n<95) box.variantNext=6;
474
                else if (n<98) box.variantNext=7;
475
                else box.variantNext=8;
476
                break;
477
        }
478
}
479
 
480
 
481
 
482
// проверка пространства снизу
483
u8 CheckDown()
484
{
485
        for(i=1;i<=HIGH_MAP-1;++i)
486
                {
487
                        if (map[i][box.col]!=0)
488
                        {
489
                                yLimit=i-1;
490
                                break;
491
                        }
492
                        else yLimit=HIGH_MAP-2;
493
                }
494
        return yLimit;
495
}
496
 
497
 
498
 
499
// проверка на коллизии
500
void Collision(u8 str, u8 col)
501
{
502
 
503
        if (map[str][col]!=map[str+1][col])
504
        {
505
                DrawTileBox(box.str,box.col,box.variant);
506
                if (gN==0) sfx_play(SFX_DEFINE,8);
507
                gN=0;
508
 
509
                if (str==1) // конец игры
510
                {
511
                        sfx_play(SFX_GAMEOVER,8);
512
                        vsync();
513
                        GameOver();
514
                        InitScreen(); // новая игра
515
                        return;
516
                }
517
        }
518
 
519
        if (map[str][col]==map[str+1][col])
520
        {
521
                switch (gN)
522
                {
523
                        case 0:
524
                        sfx_play(SFX_BELL5,8);
525
                        break;
526
                        case 1:
527
                        sfx_play(SFX_BELL4,8);
528
                        break;
529
                        case 2:
530
                        sfx_play(SFX_BELL3,8);
531
                        break;
532
                        case 3:
533
                        sfx_play(SFX_BELL2,8);
534
                        break;
535
                        case 4:
536
                        sfx_play(SFX_BELL1,8);
537
                        break;
538
                        default:
539
                        sfx_play(SFX_BELL0,8);
540
                }
541
                map[str+1][col]+=1;
542
                map[str][col]=0;
543
                if (gN>0) DrawTileBox(box.str,box.col,10);
544
                for (i=0;i<8;++i)
545
                {
546
                        box.y+=2;
547
                        Update();
548
                }
549
                box.str++;
550
                box.variant++;
551
                gN++;
552
                score+=box.variant;
553
                if (score>=score_rotate+100) //начисление rotate за 100 score
554
                {
555
                        rotate++;
556
                        score_rotate+=100;
557
                }
558
                put_score(score, rotate);
559
                if (box.variant==10)
560
                {
561
                        map[box.str][box.col]=0;
562
                        DrawTileBox(box.str,box.col,10);
563
                        sfx_play(SFX_1024,8);
564
                        gN=0;
565
                }                      
566
        }
567
        if (gN>0)
568
        {
569
                Collision(box.str,box.col);
570
        }
571
        if (boxReel<(map[box.str][box.col]-1)&&boxReel<8) boxReel++;
572
        gN=0;
573
}
574
 
575
 
576
// обмен кубиков
577
void Substitution()
578
{
579
        sfx_play(SFX_SUB,8);
580
        for (i=0;i<=40;i+=8)
581
        {
582
                set_sprite(0,box.x,box.y+i,box.variant);
583
                set_sprite(1,X_NEXT,Y_NEXT-i,box.variantNext);
584
                swap_screen();
585
        }
586
        for (i=0;i<=box.x-24;i+=4)
587
        {
588
                set_sprite(0,box.x-i,box.y+40,box.variant);
589
                set_sprite(1,X_NEXT+i,Y_NEXT-40,box.variantNext);
590
                swap_screen();
591
        }
592
 
593
        j=box.variant;
594
        box.variant=box.variantNext;
595
        box.variantNext=j;
596
}
597
 
598
// главный цикл
599
void main(void)
600
{
601
        u8 k;
602
 
603
        Intro();
604
        Bright();
605
        BestInit();
606
        SaveBest();
607
 
608
        load_from_file("savelist.bin");
609
        LoadBest();
610
        InitScreen();
611
        InitNewBox();
612
        Update();
613
 
614
        while(1)
615
        {
616
                vsync();
617
                k=joystick();
618
                if(k&JOY_UP)
619
                {
620
                        if (rotate>0)
621
                        {
622
                                rotate-=1;
623
                                put_score(score,rotate);
624
                                Substitution();
625
                        }
626
                }
627
                if(k&JOY_RIGHT&&box.col<4)
628
                {
629
                        sfx_play(SFX_SWIPE,4);
630
                        for (i=0;i<8;i++)
631
                        {
632
                                box.x++;
633
                                Update();
634
                        }
635
                        box.col++;
636
 
637
 
638
                }
639
                if(k&JOY_LEFT&&box.col>0)
640
                {
641
                        sfx_play(SFX_SWIPE,4);
642
                        for (i=0;i<8;i++)
643
                        {
644
                                box.x--;
645
                                Update();
646
                        }
647
                        box.col--;
648
 
649
                }
650
                if(k&JOY_DOWN)
651
                {
652
                        CheckDown();
653
 
654
                        while (box.str<yLimit) // движение вниз
655
                        {
656
                                for (i=0;i<2;i++)
657
                                {
658
                                        box.y+=8;
659
                                        Update();
660
                                }
661
                                box.str++;
662
                        }
663
                        map[box.str][box.col]=(box.variant+1);
664
                        Collision(box.str, box.col);
665
                        InitNewBox();
666
                        Update();
667
                        while (joystick());
668
                }
669
        }
670
}