source: cacatris/trunk/src/main.c @ 1126

Last change on this file since 1126 was 1126, checked in by Jean-Yves Lamoureux, 15 years ago
  • Displays current completed lines count
  • Property svn:keywords set to Id
File size: 8.8 KB
Line 
1/*
2 *   $Id: main.c 1126 2006-09-28 08:37:09Z jylam $
3 *
4 *   This program is free software; you can redistribute it and/or
5 *   modify it under the terms of the Do What The Fuck You Want To
6 *   Public License, Version 2, as published by Sam Hocevar. See
7 *   http://sam.zoy.org/wtfpl/COPYING for more details.
8 */
9
10#include "config.h"
11#include "cacatris.h"
12
13int main(int argc, char *argv[])
14{
15    static caca_display_t *dp;
16    signed   int x=(FIELD_WIDTH/2)-1, y=0, rotation=0, old_x=0, old_y=0, old_rotation=0;
17    unsigned int current_piece, next_piece, baseTime = 0;
18    unsigned char last_has_landed = 1;
19    unsigned char left = 0, right = 0, down = 0;
20    unsigned long long int curTime = 0;
21    unsigned int speed = 16;
22    unsigned int fixed_y = 0;
23    unsigned char lost = 0;
24    unsigned int  score = 0;
25    unsigned int lines = 0;
26    unsigned char level = 0;
27    unsigned char total_lines = 0;
28
29    field = cucul_create_canvas(0, 0);
30    infos = cucul_create_canvas(0, 0);
31    screen = cucul_create_canvas(0, 0);
32
33    dp = caca_create_display(screen);
34    if(!dp)
35        return 1;
36
37    cucul_set_canvas_size(infos, INFO_WIDTH, cucul_get_canvas_height(screen));
38    cucul_set_canvas_size(field, FIELD_CANVAS_WIDTH, FIELD_CANVAS_HEIGHT);
39
40    caca_set_display_time(dp, 20000);
41
42    /* Our playfied */
43    memset(playfield, 0, FIELD_WIDTH*FIELD_HEIGHT);
44
45
46    /* Set current and next piece to random */
47    current_piece = cucul_rand(0, 6);
48    next_piece = cucul_rand(0, 6);
49
50
51    for(;;)
52    {
53        caca_event_t ev;
54        left = 0; right = 0; down = 0;
55
56        /* Handle events */
57        while(caca_get_event(dp, CACA_EVENT_KEY_PRESS
58                             | CACA_EVENT_QUIT, &ev, 0))
59        {
60            if(ev.type == CACA_EVENT_QUIT)
61                goto end;
62            switch(ev.data.key.ch)
63            {
64            case CACA_KEY_ESCAPE:
65                goto end;
66                break;
67            case CACA_KEY_UP:
68                if(movable(current_piece, x, y, (rotation+1)&0x03))
69                {
70                    rotation++;
71                    rotation = rotation&0x03;
72                }
73                break;
74            case CACA_KEY_DOWN:
75                down = 1;
76                break;
77            case CACA_KEY_LEFT:
78                left = 1;
79                break;
80            case CACA_KEY_RIGHT:
81                right = 1;
82                break;
83            }
84        }
85
86        if(lost) continue;
87
88
89        if(y==0 && has_landed(current_piece, x ,y, rotation)) {
90            lost = 1;
91            continue;
92        }
93
94        if(left)
95        {
96            if(movable(current_piece, x-1, y, rotation))
97                x--;
98        }
99        if(right)
100        {
101            if(movable(current_piece, x+1, y, rotation))
102                x++;
103        }
104        if(down)
105        {
106            while((movable(current_piece, x, y, rotation)) && (!has_landed(current_piece, x, y, rotation)))
107            {
108                fixed_y+=speed;
109                y = fixed_y>>8;
110            }
111        }
112
113        if(!last_has_landed)
114        {
115            last_has_landed = 0;
116        }
117        else
118        {
119            last_has_landed = 0;
120        }
121
122
123        old_x = x;
124        old_y = y;
125        old_rotation = rotation;
126
127        fixed_y+=speed; /* Fixed point */
128        y = fixed_y>>8;
129
130
131
132        /* Populate info canvas */
133        infos_populate(infos, score, level, total_lines);
134        /* Draw everything on playfield */
135        put_piece(current_piece, x ,y, rotation);
136        playfield_draw(field);
137        remove_piece(current_piece, x ,y, rotation);
138        /* blit infos canvas into general one */
139        cucul_blit(screen, (cucul_get_canvas_width(screen))  - INFO_WIDTH, 0, infos, NULL);
140        /* blit playfield canvas into general one */
141        cucul_blit(screen, 18, 0, field, NULL);
142
143        caca_refresh_display(dp);
144
145
146        if(has_landed(current_piece, x ,y, rotation))
147        {
148            put_piece(current_piece, x ,y, rotation);
149            fixed_y = 0;
150            x = (FIELD_WIDTH/2)-1;
151            current_piece = next_piece;
152            rotation = 0;
153            next_piece = cucul_rand(0, 6);
154            last_has_landed = 1;
155            old_x = x;
156            old_y = 0;
157        }
158
159        lines = maybe_remove_line();
160        if(lines)
161        {
162            score += points[level+(lines-1)*LEVEL_COUNT];
163            total_lines += lines;
164            if(total_lines >=10 && level<=10)
165            {
166                level++;
167                total_lines = 0;
168                speed+=4;
169                memset(playfield, 0, FIELD_WIDTH*FIELD_HEIGHT);
170            }
171        }
172
173        if(!baseTime)
174        {
175            baseTime = caca_get_display_time(dp);
176        }
177        curTime+=caca_get_display_time(dp);
178    }
179
180 end:
181
182
183    return 0;
184}
185
186
187void infos_populate(cucul_canvas_t *inf, unsigned int score,
188                    unsigned char level, unsigned char total)
189{
190    unsigned int i;
191    char scoreline[256];
192    char levelline[256];
193    char totalline[256];
194
195    sprintf(scoreline, " Score    :   %05d ", score);
196    sprintf(levelline, " Level    :   %02d    ", level);
197    sprintf(totalline, " Lines    :   %02d    ", total);
198
199    cucul_set_color(inf, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
200    cucul_putstr(inf, 0, 0, "      =Cacatris=    ");
201    cucul_putstr(inf, 0, 1, "  Arrows  :    move ");
202    cucul_putstr(inf, 0, 2, "  Space :      pouf ");
203    cucul_putstr(inf, 0, 3, " __________________ ");
204    cucul_putstr(inf, 0, 4, "                    ");
205    cucul_putstr(inf, 0, 5, levelline);
206    cucul_putstr(inf, 0, 6, scoreline);
207    cucul_putstr(inf, 0, 7, totalline);
208    cucul_putstr(inf, 0, 8, " Time     :   XX:XX ");
209
210    for(i = 8; i < cucul_get_canvas_height(inf); i++)
211    {
212        cucul_putstr(inf, 0, i,"                     ");
213    }
214}
215
216
217void playfield_draw(cucul_canvas_t *canvas)
218{
219    unsigned int x, y;
220    float ox=0, oy=0;
221    float incx = (float)FIELD_WIDTH / (float)FIELD_CANVAS_WIDTH;
222    float incy = (float)FIELD_HEIGHT / (float)FIELD_CANVAS_HEIGHT;
223
224    for(y = 0; y < FIELD_CANVAS_WIDTH; y++)
225    {
226        for(x = 0; x < FIELD_CANVAS_WIDTH; x++)
227        {
228            unsigned int oxi = (unsigned int) ox;
229            unsigned int oyi = (unsigned int) oy;
230            unsigned int c = playfield[oxi+oyi*FIELD_WIDTH];
231            if(c) {
232                cucul_set_color(canvas, CUCUL_COLOR_BLACK, blocks_palette[c-1]);
233                cucul_putchar(canvas, x, y, ' ');
234            } else {
235                cucul_set_color(canvas, CUCUL_COLOR_BLACK, CUCUL_COLOR_DARKGRAY);
236                cucul_putchar(canvas, x, y, ' ');
237
238            }
239            ox+=incx;
240        }
241        ox = 0;
242        oy+=incy;
243    }
244}
245
246
247void put_piece(unsigned int id, unsigned int x, unsigned int y, unsigned int rot)
248{
249    unsigned int ix, iy;
250    piece_t *p = &pieces[(id*4)+rot];
251
252    for(iy = 0; iy < p->h; iy++)
253        for(ix = 0; ix < p->w; ix++)
254            if(p->data[ix+iy*4])
255                playfield[(ix+x)+(iy+y)*FIELD_WIDTH] = p->data[ix+iy*4]*p->color;
256}
257
258void remove_piece(unsigned int id, unsigned int x, unsigned int y, unsigned int rot)
259{
260    unsigned int ix, iy;
261    piece_t *p = &pieces[(id*4)+rot];
262
263    for(iy = 0; iy < p->h; iy++)
264        for(ix = 0; ix < p->w; ix++)
265            if(ix<p->w && iy<p->h)
266                if(p->data[ix+iy*4])
267                    playfield[(ix+x)+(iy+y)*FIELD_WIDTH] = 0;
268}
269
270unsigned char movable(unsigned int id, int x, int y, unsigned int rot)
271{
272    piece_t *p = &pieces[(id*4)+rot];
273    unsigned int ix, iy;
274    int w, h;
275
276    w = p->w;
277    h = p->h;
278
279
280    if(y>=(signed)(FIELD_HEIGHT-p->h)) {
281        return 0;
282    }
283
284
285    if(x>=0 && (x+w<=FIELD_WIDTH) && y<(FIELD_HEIGHT-(signed)h))
286    {
287        for(iy = 0; iy < p->h; iy++)
288            for(ix = 0; ix < p->w; ix++)
289                if((p->data[ix+iy*4]!=0) && (playfield[(ix+x)+(iy+y)*FIELD_WIDTH]!=0)) {
290                    return 0;
291                }
292
293        return 1;
294    }
295
296    return 0;
297}
298
299unsigned char has_landed(unsigned int id, unsigned int x, unsigned int y, unsigned int rot)
300{
301    piece_t *p = &pieces[(id*4)+rot];
302    unsigned int ix, iy;
303    unsigned int w, h;
304
305    w = p->w;
306    h = p->h;
307
308    if(y>=(FIELD_HEIGHT-p->h)) {
309        return 1;
310    }
311    y++;
312    if(x>=0 && (x+w<=FIELD_WIDTH) && y<=(FIELD_HEIGHT-h))
313    {
314        for(iy = 0; iy < p->h && (iy+y<FIELD_HEIGHT) ; iy++)
315            for(ix = 0; (ix < p->w) && (ix+x<FIELD_WIDTH); ix++)
316                if((p->data[ix+iy*4]!=0) && (playfield[(ix+x)+(iy+y)*FIELD_WIDTH]!=0)) {
317                    return 1;
318                }
319
320        return 0;
321    }
322    return 1;
323}
324
325
326unsigned char maybe_remove_line(void)
327{
328    int y, x, v=0;
329    unsigned char *p = playfield;
330    int ret = 0;
331
332    for(y = 0; y < FIELD_HEIGHT ; y++)
333    {
334        for(x = 0; x < FIELD_WIDTH ; x++)
335            if(*p++)
336                v++;
337        if(v==FIELD_WIDTH) {
338            memmove(&playfield[FIELD_WIDTH], playfield, (y)*FIELD_WIDTH);
339            ret++;
340        }
341        v=0;
342    }
343
344    return ret;
345}
Note: See TracBrowser for help on using the repository browser.