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

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