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

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