dbus function is done
[shermanaquarium] / sherman-aquarium / shermans / tetris.c
1
2 /* 
3    Tetris for Sherman's aquarium by Jonas Aaberg <cja@gmx.net>
4
5 */
6
7
8 /*
9    On their spare time, some reads a book, some goes shopping, 
10    some do sports, some spends time with friends, and one
11    sits programming yet another tetris version and listens to
12    Sonata Arctica... 
13
14    Strange world, isn't it?
15
16 */
17   
18
19 #include "tetris.h"
20 #include "aquarium.h"
21 #include "over.h"
22 #include "settings.h"
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <gdk/gdkkeysyms.h>
27
28 #define X 0
29 #define Y 1
30 #define PIECES 7
31 #define FIGURES 10
32 #define STATUS 4
33 #define TOP10 0
34 #define LINES 1
35 #define SCORE 2
36 #define LEVEL 3
37
38 static int pieces[PIECES][4][2] = {
39     { {0, 1}, {1, 1}, {2, 1}, {3, 1} },
40     { {0, 1}, {1, 1}, {2, 1}, {2, 2} },
41     { {0, 2}, {1, 2}, {2, 2}, {2, 1} },
42     { {0, 2}, {1, 1}, {1, 2}, {2, 2} },
43     { {0, 2}, {1, 2}, {1, 1}, {2, 1} },
44     { {0, 1}, {1, 1}, {1, 2}, {2, 2} },
45     { {1, 1}, {2, 1}, {1, 2}, {2, 2} }
46 };
47
48 static int board_x;
49 static int board_y;
50
51 static Tetris_highscore_table highscores[11];
52 static Tetris_settings tetris_settings;
53
54 static int *board;
55
56 static int curr_piece_num;
57 static int next_piece_num;
58
59 static int location[2];
60 static int curr_piece[4][2];
61 static int gameover, firsttime;
62 static int show_highscore_upper;
63
64 static SA_Image tetris_pieces, tetris_figures, tetris_figures2;
65 static SA_Image tetris_status, tetris_gameover;
66
67 static int delay;
68 static int counter;
69 static int has_highscore, use_font2;
70
71 static int death = 0;
72
73 static unsigned char* tetris_background;
74
75 static int score, level, lines;
76 static int horizontal;
77
78 Tetris_highscore_table *tetris_get_highscore_table_ptr(void)
79 {
80     return highscores;
81 }
82
83 Tetris_settings *tetris_get_settings_ptr(void)
84 {
85     return &tetris_settings;
86 }
87
88 void prepare_tetris_background()
89 {
90     int x,y,ypos, R,G,B;
91     AquariumData *ad;
92
93     ad= aquarium_get_settings_ptr();
94
95     //printf("prepare tetris background\n");
96
97     tetris_background = g_malloc0(ad->ymax * ad->xmax * 4); 
98
99     if(horizontal){
100         for(y = 0; y < ad->ymax; y++){
101             ypos = y * ad->xmax * 4;
102             for(x = 0; x < ad->xmax; x++){
103                 if((y == 0 || y == ((board_y) * tetris_pieces.height + 1))
104                    && x <= (board_x * (tetris_pieces.width))){
105                     R = 0xab;
106                     G = 0xba;
107                     B = 0xc6;
108                 } else if (x == (board_x * (tetris_pieces.width)) &&
109                            y >= 0 && y < (board_y) * tetris_pieces.height + 1){
110                     R = 0xab;
111                     G = 0xba;
112                     B = 0xc6;
113                 }
114                 else{
115                     R = G = B = 0;
116                 }
117
118                 tetris_background[ypos + x * 4 + 0] = R;
119                 tetris_background[ypos + x * 4 + 1] = G;
120                 tetris_background[ypos + x * 4 + 2] = B;
121                 tetris_background[ypos + x * 4 + 3] = 0xff;
122             }
123
124         }
125     }
126     else {
127         for(y = 0; y < ad->ymax; y++){
128             ypos = y * ad->xmax * 4;
129             for(x = 0; x < ad->xmax; x++){
130                 if((x == 2 || x == ((board_x + 1) * tetris_pieces.width - 1))
131                    && y <= (board_y * (tetris_pieces.height))){
132                     R = 0xab;
133                     G = 0xba;
134                     B = 0xc6;
135                 } else if (y == (board_y * (tetris_pieces.height)) &&
136                            x >= 2 && x < (board_x + 1) * tetris_pieces.width){
137                     R = 0xab;
138                     G = 0xba;
139                     B = 0xc6;
140
141
142                 }
143                 else{
144                     R = G = B = 0;
145                 }
146
147                 tetris_background[ypos + x * 4 + 0] = R;
148                 tetris_background[ypos + x * 4 + 1] = G;
149                 tetris_background[ypos + x * 4 + 2] = B;
150                 tetris_background[ypos + x * 4 + 3] = 0xff;
151             }
152
153         }
154     }
155
156 }
157
158 void tetris_exit(void)
159 {
160     //printf("tetris exit\n");
161     if(board != NULL)
162         g_free(board);
163     if(tetris_background != NULL)
164         g_free(tetris_background);
165
166     board = NULL;
167     tetris_background = NULL;
168 }
169
170 void tetris_restart(void)
171 {
172     int i,x,y,tbx;
173     AquariumData *ad;
174
175     if(board != NULL)
176         tetris_exit();
177
178     //    printf("tetris restart\n");
179
180     ad = aquarium_get_settings_ptr();
181
182     //printf("xmax %d ymax %d\n", ad->xmax, ad->ymax);
183
184     board_x = (ad->xmax - 24) / tetris_pieces.width;
185     board_y = (ad->ymax - 2) / tetris_pieces.height;
186
187     if(tetris_settings.size_limit){
188         if(board_x > tetris_settings.width)
189             board_x = tetris_settings.width;
190
191         if(board_y > tetris_settings.height)
192             board_y = tetris_settings.height;
193
194     }
195
196
197
198     //printf("Board_x %d, board_y %d\n", board_x, board_y);
199
200     if(2 * ad->xmax / 3 > ad->ymax){
201         horizontal = 1;
202         x = Y;
203         y = X;
204         tbx = board_y;
205     }
206     else {
207         horizontal = 0;
208         x = X;
209         y = Y;
210         tbx = board_x;
211     }
212
213
214     //printf("Board_x %d, board_y %d\n", board_x, board_y);
215     board = NULL;
216
217     if(gai_load_int_with_default("tetris/board_x", -1) == board_x &&
218        gai_load_int_with_default("tetris/board_y", -1) == board_y && firsttime){
219         board = (int *)gai_load_raw_data("tetris/board", NULL);
220     }
221
222     if(board == NULL && death){
223         //printf("first time or die\n");
224         board = g_malloc0(board_x * board_y * sizeof(int));
225         gameover = 0;
226         score = 0;
227         lines = 0;
228         level = 1;
229         death = 0;
230         location[x] = (tbx - 4) / 2 + horizontal;
231         location[y] = -4;
232         next_piece_num = g_rand_int_range(ad->rnd, 0, PIECES);
233         curr_piece_num = g_rand_int_range(ad->rnd, 0, PIECES);
234         delay = 16;
235         for(i = 0; i < 4; i++){
236             curr_piece[i][x] = pieces[curr_piece_num][i][X];
237             curr_piece[i][y] = pieces[curr_piece_num][i][Y];
238         }
239
240
241     } else {
242         //printf("load game over\n");
243         if(board == NULL)
244             board = g_malloc0(board_x * board_y * sizeof(int));
245         gameover = gai_load_int_with_default("tetris/gameover", 0);
246         score = gai_load_int_with_default("tetris/score", 0);
247         lines = gai_load_int_with_default("tetris/lines", 0);
248         level = gai_load_int_with_default("tetris/level", 1);
249         location[x] = gai_load_int_with_default("tetris/location_x", (tbx - 4) / 2 + horizontal);
250         location[y] = gai_load_int_with_default("tetris/location_y", -4);
251         next_piece_num = gai_load_int_with_default("tetris/next_piece_num", g_rand_int_range(ad->rnd, 0, PIECES));
252         curr_piece_num = gai_load_int_with_default("tetris/curr_piece_num", g_rand_int_range(ad->rnd, 0, PIECES));
253         delay = gai_load_int_with_default("tetris/delay", 16);
254         curr_piece[0][x] = gai_load_int_with_default("tetris/curr_piece0X", 0);
255         curr_piece[0][y] = gai_load_int_with_default("tetris/curr_piece0Y", 0);
256         curr_piece[1][x] = gai_load_int_with_default("tetris/curr_piece1X", 0);
257         curr_piece[1][y] = gai_load_int_with_default("tetris/curr_piece1Y", 0);
258         curr_piece[2][x] = gai_load_int_with_default("tetris/curr_piece2X", 0);
259         curr_piece[2][y] = gai_load_int_with_default("tetris/curr_piece2Y", 0);
260         curr_piece[3][x] = gai_load_int_with_default("tetris/curr_piece3X", 0);
261         curr_piece[3][y] = gai_load_int_with_default("tetris/curr_piece3Y", 0);
262
263     }
264     firsttime = 0;
265
266     prepare_tetris_background();
267
268     use_font2 = 0;
269
270     counter = delay;
271     show_highscore_upper = 0;
272
273     has_highscore = 1979;
274
275 }
276
277 void tetris_init(void)
278 {
279     death = 0;
280     firsttime = 1;
281     //printf("tetris init\n");
282     tetris_load_highscores();
283
284     load_image("tetris_pieces.png",
285                &tetris_pieces,
286                PIECES);
287
288     load_image("tetris_figures.png",
289                &tetris_figures,
290                FIGURES);
291
292     load_image("tetris_figures2.png",
293                &tetris_figures2,
294                FIGURES);
295
296
297     load_image("tetris_status.png",
298                &tetris_status,
299                STATUS);
300
301
302     load_image("tetris_gameover.png",
303                &tetris_gameover,
304                1);
305
306     tetris_restart();
307
308 }
309
310 void check_highscore(void)
311 {
312     int i, j;
313
314     for(i = 0; i < 10; i++){
315         if(highscores[i].score<score){
316             for(j = 9; j > i; j--){
317                 highscores[i].score = highscores[j - 1].score;
318                 highscores[i].level = highscores[j - 1].level;
319                 highscores[i].lines = highscores[j - 1].lines;
320             }
321             has_highscore = i;
322             highscores[i].score = score;
323             highscores[i].level = level;
324             highscores[i].lines = lines;
325             break;
326         }
327         
328     }
329     tetris_save_highscores();
330     
331 }
332
333 void drawnextpiece(void)
334 {
335     int i, x, y;
336     AquariumData *ad;
337
338     if(!tetris_settings.show_next)
339         return;
340     ad = aquarium_get_settings_ptr();
341
342     x = ad->xmax - (tetris_pieces.width * 4 + 1);
343     y = 4;
344     
345
346     for(i = 0; i < 4; i++){
347         over_draw(x + tetris_pieces.width * pieces[next_piece_num][i][X],
348                   y + tetris_pieces.height * pieces[next_piece_num][i][Y],
349                   next_piece_num,
350                   tetris_pieces.width,
351                   tetris_pieces.height,
352                   tetris_pieces.image);
353     }
354 }
355
356 void drawfigures(int x,int y, int num)
357 {
358     SA_Image *figures;
359
360     if(use_font2) 
361         figures = &tetris_figures2;
362     else 
363         figures = &tetris_figures;
364
365
366     if(num > 99)
367         over_draw(x, y,
368                   num / 100,
369                   figures->width,
370                   figures->height,
371                   figures->image);
372
373     if(num > 9)
374         over_draw(x + figures->width, y,
375                   (num % 100) / 10,
376                   figures->width,
377                   figures->height,
378                   figures->image);
379
380     over_draw(x + figures->width * 2,y,
381               (num % 10),
382               figures->width,
383               figures->height,
384               figures->image);
385
386 }
387
388 void drawstatus(void)
389 {
390     int x, y, dy;
391
392     AquariumData *ad;
393
394     ad = aquarium_get_settings_ptr();
395
396     x = ad->xmax-tetris_figures.width * 3 - 2;
397     y = 20;
398     dy = tetris_figures.height + 3;
399
400     drawfigures(x, y, score);
401     drawfigures(x, y + dy, level);
402     drawfigures(x, y + 2 * dy, lines);
403
404 }
405
406 void draw_gameover(void)
407 {
408     AquariumData *ad;
409     ad = aquarium_get_settings_ptr();
410
411     drawstatus();
412
413     over_draw((ad->xmax-tetris_gameover.width) / 2,
414               (ad->ymax-tetris_gameover.height) / 2,
415               0,
416               tetris_gameover.width,
417               tetris_gameover.height,
418               tetris_gameover.image);
419 }
420
421 void draw_finalscore(void)
422 {
423     int x, y, dy, ypos;
424
425     AquariumData *ad;
426
427     //printf("draw_finalscore\n");
428
429     ad = aquarium_get_settings_ptr();
430
431     for(y = 0; y < ad->ymax; y++){
432         ypos = y * ad->xmax * 4;
433         for(x = 0; x <ad->xmax; x++){
434             tetris_background[ypos+x * 4 + 0] = 0;
435             tetris_background[ypos+x * 4 + 1] = 0;
436             tetris_background[ypos+x * 4 + 2] = 0;
437             tetris_background[ypos+x * 4 + 3] = 0xff;
438         }
439     }
440     over_draw(0, 0, 0, ad->xmax,ad->ymax,tetris_background);
441
442     x = (ad->xmax-tetris_status.width) / 2;
443     y = (ad->ymax-3 * (tetris_figures.height + tetris_status.height)) / 2;
444     dy = tetris_figures.height + tetris_status.height;
445     over_draw(x, y , SCORE, tetris_status.width, tetris_status.height,
446               tetris_status.image);
447     
448     over_draw(x, y + dy, LEVEL, tetris_status.width, tetris_status.height,
449               tetris_status.image);
450
451     over_draw(x, y + 2 * dy, LINES, tetris_status.width, tetris_status.height,
452               tetris_status.image);
453
454     drawfigures(x + tetris_status.width, y + tetris_status.height, score);
455     drawfigures(x + tetris_status.width, y + tetris_status.height + dy, level);
456     drawfigures(x + tetris_status.width, y + tetris_status.height + 2 * dy, lines);
457     counter = 0;
458 }
459
460
461 void draw_highscorelist(void)
462 {
463     int x, y, ypos, i, dx, sx;
464
465     AquariumData *ad;
466
467     ad = aquarium_get_settings_ptr();
468     //printf("darw_highscore\n");
469
470     for(y = 0; y < ad->ymax; y++){
471         ypos = y * ad->xmax * 4;
472         for(x = 0; x < ad->xmax; x++){
473             tetris_background[ypos + x * 4 + 0] = 0;
474             tetris_background[ypos + x * 4 + 1] = 0;
475             tetris_background[ypos + x * 4 + 2] = 0;
476             tetris_background[ypos + x * 4 + 3] = 0xff;
477         }
478     }
479     over_draw(0, 0, 0, ad->xmax, ad->ymax,tetris_background);
480
481     over_draw((ad->xmax - tetris_status.width) / 2, 1, TOP10, tetris_status.width,
482               tetris_status.height, tetris_status.image);
483
484     sx = -tetris_figures.width;
485
486     dx = ((ad->xmax-sx) - 4 * 3 * tetris_figures.width) / 4 + 3 * tetris_figures.width;
487
488     if(ad->ymax > (tetris_status.height + 10 * tetris_figures.height)){
489         for(i = 0; i < 10; i++){
490             if(i == has_highscore) 
491                 use_font2 = TRUE;
492             else 
493                 use_font2 = FALSE;
494             drawfigures(sx,
495                         8 + tetris_status.height + i * tetris_figures.height,
496                         i + 1);
497         
498             drawfigures(sx + dx,
499                         8 + tetris_status.height + i * tetris_figures.height,
500                         highscores[i].score);
501
502             drawfigures(sx + 2 * dx,
503                         8 + tetris_status.height + i * tetris_figures.height,
504                         highscores[i].lines);
505
506             drawfigures(sx + 3 * dx,
507                         8 + tetris_status.height + i * tetris_figures.height,
508                         highscores[i].level);
509         }
510
511
512     } else {
513         for(i = 5 * show_highscore_upper; i < (5 + 5 * show_highscore_upper); i++){
514             if(i == has_highscore) 
515                 use_font2 = TRUE;
516             else 
517                 use_font2 = FALSE;
518
519             drawfigures(sx,
520                         8 + tetris_status.height + (i - 5 * show_highscore_upper) * tetris_figures.height, i + 1);
521         
522             drawfigures(sx + dx,
523                          8 + tetris_status.height + (i - 5 * show_highscore_upper) * tetris_figures.height, highscores[i].score);
524             drawfigures(sx + 2 * dx,
525                         8 + tetris_status.height + (i - 5 * show_highscore_upper) * tetris_figures.height, highscores[i].lines);
526             drawfigures(sx + 3 * dx,
527                         8 + tetris_status.height + (i - 5 * show_highscore_upper) * tetris_figures.height, highscores[i].level);
528         }
529         counter++;
530         if(counter == 100){
531             show_highscore_upper = !show_highscore_upper;
532             counter = 0;
533         }
534     }
535        
536
537
538 }
539
540 void drawboardonscreen(void)
541 {
542     int x, y;
543
544     AquariumData *ad;
545
546     ad = aquarium_get_settings_ptr();
547     //    printf("drawongscreen %d\n", gameover);
548
549     switch(gameover){
550
551     /* Normal play */
552     case 0:
553
554         over_draw(0 ,0 ,0, ad->xmax, ad->ymax, tetris_background);
555         //printf("%d %d\n", board_x, board_y);
556         for(y = 0; y < board_y; y++){
557             for(x = 0;x < board_x; x++){
558
559                 if(board[y * board_x + x] != 0)
560                     over_draw(x * tetris_pieces.width + 3 * !horizontal,
561                               y * tetris_pieces.height + horizontal,
562                               board[y * board_x + x] - 1,
563                               tetris_pieces.width,
564                               tetris_pieces.height,
565                               tetris_pieces.image);
566             }
567         }
568         //printf("for done\n");
569         drawnextpiece();
570         drawstatus();
571         break;
572
573     case 1:
574         draw_gameover();
575         break;
576     case 2:
577         draw_finalscore();
578         break;
579     
580     case 3:
581         draw_highscorelist();
582
583         break;
584     default:
585         break;
586     }
587
588 }
589
590 void manageboard(int piece[4][2], int location[2], int colour)
591 {
592     int i;
593
594     //    printf("manageboard\n");
595
596     for(i = 0; i < 4; i++){
597         if(location[X] + piece[i][X] >= 0 && location[Y] + piece[i][Y] >=0)
598             board[(location[X] + piece[i][X]) + (location[Y] + piece[i][Y]) * board_x]
599             = colour;
600     }
601     //    printf("manage board done\n");
602 }
603
604 void removefromboard(int piece[4][2],int location[2])
605 {
606     manageboard(piece, location, 0);
607 }
608
609
610 void drawonboard(int piece[4][2],int location[2])
611 {
612     manageboard(piece, location, curr_piece_num + 1);
613 }
614
615
616 /* 
617    Returns: 
618    0 = Movement ok.
619    1 = Landed upon piece.
620    2 = Tried to move outside X wise.
621    3 = Landed upon piece and tried to move too far X wise. 
622    4 = Landed on bottom.
623    5 = Landed on bottom & piece.
624    6 = landed on bottom & X outside.
625    7 = landed on bottom & X outside & piece.
626 */
627
628 int movepiece(int piece[4][2],int new_location[2])
629 {
630     int i;
631     int stuck = 0;
632
633     int x, y, tbx, tby;
634         
635
636     //    printf("movepiece\n");
637
638     if(horizontal){
639         x = Y;
640         y = X;
641         tbx = board_y;
642         tby = board_x;
643         
644     } else{
645         x = X;
646         y = Y;
647         tbx = board_x;
648         tby = board_y;
649     }
650
651
652
653     for(i = 0;i < 4; i++){
654         /* Edges */
655         if(new_location[x] + piece[i][x] >= tbx || new_location[x] + piece[i][x]<0){
656             stuck |= 2;
657             continue;
658         }
659         /* Bottom */
660         if(new_location[y] + piece[i][y] == tby){
661             stuck |= 4;
662             continue;
663         }
664         /* Upon other pieces */
665         if(new_location[y] + piece[i][y] >= 0)
666             if(board[(new_location[X] + piece[i][X]) + (new_location[Y] + piece[i][Y]) * board_x]!=0)
667                 stuck |= 1;
668     }
669     return stuck;
670
671 }
672
673 void rotatepiece(int piece[4][2], int location[2])
674 {
675     int tmp_piece[4][2], i;
676
677     //    printf("rotate piece\n");
678
679     for(i= 0 ; i < 4; i++){
680         tmp_piece[i][X] = 3 - piece[i][Y];
681         tmp_piece[i][Y] = piece[i][X];
682     }
683
684     if(movepiece(tmp_piece, location) == 0){
685         for(i = 0; i < 4; i++){
686             piece[i][X] = tmp_piece[i][X];
687             piece[i][Y] = tmp_piece[i][Y];
688         }
689     }
690        
691 }
692
693 void removeline(int line)
694 {
695     int x, y;
696     //    printf("removeline\n");
697
698     if(horizontal){
699         for(x = line; x > 0; x--){
700             for(y = 0; y < board_y; y++){
701                 board[x + y * board_x] = board[(x - 1) + y * board_x];
702             }
703         }
704         for(y = 0; y < board_y; y++)
705             board[y * board_x] = 0;
706     }
707     else {
708         for(y = line; y > 0; y--){
709             for(x = 0; x < board_x; x++){
710                 board[x + y * board_x] = board[x + (y - 1) * board_x];
711             }
712         }
713         for(x = 0; x < board_x; x++)
714             board[x] = 0;
715     }
716
717
718 }
719
720 void checkforline(void)
721 {
722
723     int gotline = 0, tot_lines = 0;
724     int x, y;
725     int points[] = {0, 1 , 3 , 5, 9};
726
727     //    printf("checkforline\n");
728
729     if(horizontal){
730         for(x = 0; x < board_x; x++){
731             gotline = 1;
732             for(y = 0; y < board_y; y++){
733                 if(board[x + y * board_x] == 0) 
734                     gotline=0;
735             }
736             if(gotline){
737                 tot_lines++;
738                 removeline(x);
739                 /* Restart */
740                 x = 0;
741             }
742         }
743     }  
744     else {
745         for(y = 0; y < board_y; y++){
746             gotline = 1;
747             for(x = 0; x < board_x; x++){
748                 if(board[x + y * board_x] == 0) gotline = 0;
749             }
750             if(gotline){
751                 tot_lines++;
752                 removeline(y);
753                 /* Restart */
754                 y = 0;
755             }
756         }
757     }
758
759     if(tot_lines>0){
760         lines += tot_lines;
761
762         score += points[tot_lines];
763
764         if(((lines - tot_lines) / 10) < lines / 10){
765             level++;
766             if(delay > 0) delay--;
767         }
768         /*      printf("Score %d Lines %d Level %d\n",score,lines,level);*/
769     }
770
771 }
772
773 void tetris_update(void)
774 {
775     int answer;
776     int i, x, y, tbx;
777     AquariumData *ad;
778
779     ad = aquarium_get_settings_ptr();
780
781
782     if(gameover != 0 || delay != counter){
783         drawboardonscreen();
784         counter++;
785         return;
786     }
787
788     counter = 0;
789
790     removefromboard(curr_piece, location);
791
792     if(horizontal){
793         x = Y;
794         y = X;
795         tbx = board_y;
796     }
797     else {
798         x = X;
799         y = Y;
800         tbx = board_x;
801     }
802
803     location[y]++;
804
805     answer = movepiece(curr_piece, location);
806
807     if(answer == 0){
808         drawonboard(curr_piece, location);
809     }
810     if((answer & 4) == 4 || (answer & 1) == 1){
811
812         location[y]--;
813
814         drawonboard(curr_piece, location);
815
816         checkforline();
817
818         for(i = 0; i < 4; i++){
819             if((curr_piece[i][y] + location[y]) < 0) 
820                 gameover = 1;
821         }
822
823         if(gameover == 0){
824             location[y] = -4;
825             location[x] = (tbx - 4) / 2 + horizontal;
826         
827             for(i = 0; i < 4; i++){
828                 curr_piece[i][x] = pieces[next_piece_num][i][X];
829                 curr_piece[i][y] = pieces[next_piece_num][i][Y];
830             }
831             curr_piece_num = next_piece_num;
832             next_piece_num = g_rand_int_range(ad->rnd, 0, PIECES);
833
834             answer = movepiece(curr_piece, location);
835             if(answer != 0) gameover = 1;
836         }
837         else{
838             check_highscore();
839         }
840
841     }
842     
843     drawboardonscreen();
844
845
846 }
847
848
849 void tetris_keypress(int key)
850 {
851     int x, y;
852
853     removefromboard(curr_piece, location);
854
855     if(gameover == 4){
856         death = 1;
857         tetris_restart();
858         return;
859     }
860
861     if(horizontal){
862         x = Y;
863         y = X;
864     }
865     else {
866         x = X;
867         y = Y;
868     }
869
870     switch(key){
871     case GDK_Up:
872         rotatepiece(curr_piece, location);
873         break;
874     case GDK_Left:
875         location[x]--;
876         if(movepiece(curr_piece, location)!=0)
877             location[x]++;
878
879         break;
880     case GDK_Right:
881         location[x]++;
882         if(movepiece(curr_piece, location)!=0)
883             location[x]--;
884         break;
885     case GDK_Down:
886         if(gameover != 0) {
887             gameover++;
888         }
889         location[y]++;
890         if(movepiece(curr_piece, location)!=0)
891             location[y]--;
892
893         break;
894     default:
895         break;
896     }
897
898     drawonboard(curr_piece, location);
899
900 }
901
902 void tetris_joystick(GaiFlagsJoystick js)
903 {
904     int key = 0;
905     if(js & GAI_JOYSTICK_LEFT)
906         key |= GDK_Left;
907     if(js & GAI_JOYSTICK_RIGHT)
908         key |= GDK_Right;
909     if(js & GAI_JOYSTICK_UP)
910         key |= GDK_Up;
911     if(js & GAI_JOYSTICK_BUTTON_A)
912         key |= GDK_Up;
913     if(js & GAI_JOYSTICK_BUTTON_B)
914         key |= GDK_Down;
915     if(js & GAI_JOYSTICK_DOWN)
916         key |= GDK_Down;
917     tetris_keypress(key);
918
919 }
920
921 void tetris_start(void)
922 {
923     //printf("tetris start\n");
924 }
925
926 void tetris_end(void)
927 {
928     int x, y, tbx;
929     AquariumData *ad;
930     //printf("tetris end\n");
931
932     ad = aquarium_get_settings_ptr();
933
934     if(2 * ad->xmax / 3 > ad->ymax){
935         horizontal = 1;
936         x = Y;
937         y = X;
938         tbx = board_y;
939     }
940     else {
941         horizontal = 0;
942         x = X;
943         y = Y;
944         tbx = board_x;
945     }
946
947     //printf("Board_x %d, board_y %d\n", board_x, board_y);
948
949     gai_save_int("tetris/board_x", board_x);
950     gai_save_int("tetris/board_y", board_y);
951     gai_save_int("tetris/gameover", gameover);
952     gai_save_int("tetris/score", score);
953     gai_save_int("tetris/lines", lines);
954     gai_save_int("tetris/level", level);
955     gai_save_int("tetris/location_x", location[x]);
956     gai_save_int("tetris/location_y", location[y]);
957     gai_save_int("tetris/next_piece_num", next_piece_num);
958     gai_save_int("tetris/curr_piece_num", curr_piece_num);
959     gai_save_int("tetris/delay", delay);
960     gai_save_raw_data("tetris/board", (unsigned char *)board, board_y * board_x * sizeof(int));
961
962     gai_save_int("tetris/curr_piece0X", curr_piece[0][x]);
963     gai_save_int("tetris/curr_piece0Y", curr_piece[0][y]);
964     gai_save_int("tetris/curr_piece1X", curr_piece[1][x]);
965     gai_save_int("tetris/curr_piece1Y", curr_piece[1][y]);
966     gai_save_int("tetris/curr_piece2X", curr_piece[2][x]);
967     gai_save_int("tetris/curr_piece2Y", curr_piece[2][y]);
968     gai_save_int("tetris/curr_piece3X", curr_piece[3][x]);
969     gai_save_int("tetris/curr_piece3Y", curr_piece[3][y]);
970
971 }