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

Last change on this file since 1311 was 1311, checked in by Sam Hocevar, 13 years ago
  • Update code to make use of libcaca 0.99.beta9.
  • Property svn:keywords set to Id
File size: 8.8 KB
Line 
1/*
2 *   $Id: main.c 1311 2006-11-09 10:52:31Z sam $
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    caca_free_display(dp);
182    cucul_free_canvas(field);
183    cucul_free_canvas(infos);
184    cucul_free_canvas(screen);
185
186    return 0;
187}
188
189
190void infos_populate(cucul_canvas_t *inf, unsigned int score,
191                    unsigned char level, unsigned char total)
192{
193    unsigned int i;
194    char scoreline[256];
195    char levelline[256];
196    char totalline[256];
197
198    sprintf(scoreline, " Score    :   %05d ", score);
199    sprintf(levelline, " Level    :   %02d    ", level);
200    sprintf(totalline, " Lines    :   %02d    ", total);
201
202    cucul_set_color_ansi(inf, CUCUL_WHITE, CUCUL_BLUE);
203    cucul_putstr(inf, 0, 0, "      =Cacatris=    ");
204    cucul_putstr(inf, 0, 1, "  Arrows  :    move ");
205    cucul_putstr(inf, 0, 2, "  Space :      pouf ");
206    cucul_putstr(inf, 0, 3, " __________________ ");
207    cucul_putstr(inf, 0, 4, "                    ");
208    cucul_putstr(inf, 0, 5, levelline);
209    cucul_putstr(inf, 0, 6, scoreline);
210    cucul_putstr(inf, 0, 7, totalline);
211    cucul_putstr(inf, 0, 8, " Time     :   XX:XX ");
212
213    for(i = 8; i < cucul_get_canvas_height(inf); i++)
214    {
215        cucul_putstr(inf, 0, i,"                     ");
216    }
217}
218
219
220void playfield_draw(cucul_canvas_t *canvas)
221{
222    unsigned int x, y;
223    float ox=0, oy=0;
224    float incx = (float)FIELD_WIDTH / (float)FIELD_CANVAS_WIDTH;
225    float incy = (float)FIELD_HEIGHT / (float)FIELD_CANVAS_HEIGHT;
226
227    for(y = 0; y < FIELD_CANVAS_WIDTH; y++)
228    {
229        for(x = 0; x < FIELD_CANVAS_WIDTH; x++)
230        {
231            unsigned int oxi = (unsigned int) ox;
232            unsigned int oyi = (unsigned int) oy;
233            unsigned int c = playfield[oxi+oyi*FIELD_WIDTH];
234            cucul_set_color_ansi(canvas, CUCUL_BLACK,
235                                 c ? blocks_palette[c-1] : CUCUL_DARKGRAY);
236            cucul_putchar(canvas, x, y, ' ');
237            ox+=incx;
238        }
239        ox = 0;
240        oy+=incy;
241    }
242}
243
244
245void put_piece(unsigned int id, unsigned int x, unsigned int y, unsigned int rot)
246{
247    unsigned int ix, iy;
248    piece_t *p = &pieces[(id*4)+rot];
249
250    for(iy = 0; iy < p->h; iy++)
251        for(ix = 0; ix < p->w; ix++)
252            if(p->data[ix+iy*4])
253                playfield[(ix+x)+(iy+y)*FIELD_WIDTH] = p->data[ix+iy*4]*p->color;
254}
255
256void remove_piece(unsigned int id, unsigned int x, unsigned int y, unsigned int rot)
257{
258    unsigned int ix, iy;
259    piece_t *p = &pieces[(id*4)+rot];
260
261    for(iy = 0; iy < p->h; iy++)
262        for(ix = 0; ix < p->w; ix++)
263            if(ix<p->w && iy<p->h)
264                if(p->data[ix+iy*4])
265                    playfield[(ix+x)+(iy+y)*FIELD_WIDTH] = 0;
266}
267
268unsigned char movable(unsigned int id, int x, int y, unsigned int rot)
269{
270    piece_t *p = &pieces[(id*4)+rot];
271    unsigned int ix, iy;
272    int w, h;
273
274    w = p->w;
275    h = p->h;
276
277
278    if(y>=(signed)(FIELD_HEIGHT-p->h)) {
279        return 0;
280    }
281
282
283    if(x>=0 && (x+w<=FIELD_WIDTH) && y<(FIELD_HEIGHT-(signed)h))
284    {
285        for(iy = 0; iy < p->h; iy++)
286            for(ix = 0; ix < p->w; ix++)
287                if((p->data[ix+iy*4]!=0) && (playfield[(ix+x)+(iy+y)*FIELD_WIDTH]!=0)) {
288                    return 0;
289                }
290
291        return 1;
292    }
293
294    return 0;
295}
296
297unsigned char has_landed(unsigned int id, unsigned int x, unsigned int y, unsigned int rot)
298{
299    piece_t *p = &pieces[(id*4)+rot];
300    unsigned int ix, iy;
301    unsigned int w, h;
302
303    w = p->w;
304    h = p->h;
305
306    if(y>=(FIELD_HEIGHT-p->h)) {
307        return 1;
308    }
309    y++;
310    if(x>=0 && (x+w<=FIELD_WIDTH) && y<=(FIELD_HEIGHT-h))
311    {
312        for(iy = 0; iy < p->h && (iy+y<FIELD_HEIGHT) ; iy++)
313            for(ix = 0; (ix < p->w) && (ix+x<FIELD_WIDTH); ix++)
314                if((p->data[ix+iy*4]!=0) && (playfield[(ix+x)+(iy+y)*FIELD_WIDTH]!=0)) {
315                    return 1;
316                }
317
318        return 0;
319    }
320    return 1;
321}
322
323
324unsigned char maybe_remove_line(void)
325{
326    int y, x, v=0;
327    unsigned char *p = playfield;
328    int ret = 0;
329
330    for(y = 0; y < FIELD_HEIGHT ; y++)
331    {
332        for(x = 0; x < FIELD_WIDTH ; x++)
333            if(*p++)
334                v++;
335        if(v==FIELD_WIDTH) {
336            memmove(&playfield[FIELD_WIDTH], playfield, (y)*FIELD_WIDTH);
337            ret++;
338        }
339        v=0;
340    }
341
342    return ret;
343}
Note: See TracBrowser for help on using the repository browser.