source: libcaca/trunk/src/tunnel.c @ 51

Last change on this file since 51 was 51, checked in by Sam Hocevar, 18 years ago
  • added support for --disable-slang.
  • fixed an overflow in the tunnel update code.
  • fragbomb is now 'f', not 'd'.
  • added a missing call to init_bonus().
File size: 4.1 KB
Line 
1/*
2 *   ttyvaders     Textmode shoot'em up
3 *   Copyright (c) 2002 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
6 *   $Id: tunnel.c,v 1.6 2002/12/23 10:06:27 sam Exp $
7 *
8 *   This program is free software; you can redistribute it and/or modify
9 *   it under the terms of the GNU General Public License as published by
10 *   the Free Software Foundation; either version 2 of the License, or
11 *   (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <stdlib.h>
24
25#include "common.h"
26
27static void draw_wall( game *g, int *wall, int delta );
28
29/* Init tunnel */
30tunnel * create_tunnel( game *g, int w, int h )
31{
32    int i;
33    tunnel *t = malloc(sizeof(tunnel));
34
35    t->left = malloc(h*sizeof(int));
36    t->right = malloc(h*sizeof(int));
37    t->w = w;
38    t->h = h;
39
40    if( t->w >= g->w )
41    {
42        for( i = 0; i < g->h; i++ )
43        {
44            t->left[i] = -10;
45            t->right[i] = g->w + 10;
46        }
47    }
48    else
49    {
50        t->left[0] = (g->w - w) / 2;
51        t->right[0] = (g->w + w) / 2;
52        /* Yeah, sub-efficient, but less code to do :-) */
53        for( i = 0; i < g->h; i++ )
54        {
55            update_tunnel( g, t );
56        }
57    }
58
59    return t;
60}
61
62void free_tunnel( tunnel *t )
63{
64    free( t->left );
65    free( t->right );
66    free( t );
67}
68
69void draw_tunnel( game *g, tunnel *t )
70{
71    /* Print tunnel */
72    draw_wall( g, t->left, -2 );
73    draw_wall( g, t->right, -1 );
74}
75
76void update_tunnel( game *g, tunnel *t )
77{
78    static int const delta[] = { -3, -2, -1, 1, 2, 3 };
79    int i,j,k;
80
81    /* Slide tunnel one block vertically */
82    for( i = t->h - 1; i--; )
83    {
84        t->left[i+1] = t->left[i];
85        t->right[i+1] = t->right[i];
86    }
87
88    /* Generate new values */
89    i = delta[GET_RAND(0,6)];
90    j = delta[GET_RAND(0,6)];
91
92    /* Check in which direction we need to alter tunnel */
93    if( t->right[1] - t->left[1] < t->w )
94    {
95        /* Not wide enough */
96        if( i > j )
97        {
98            k = j; j = i; i = k;
99        }
100    }
101    else if( t->right[1] - t->left[1] - 2 > t->w )
102    {
103        /* Too wide */
104        if( i < j )
105        {
106            k = j; j = i; i = k;
107        }
108    }
109    else
110    {
111        /* No need to mess with i and j: width is OK */
112    }
113
114    /* If width doesn't exceed game size, update coords */
115    if( t->w <= g->w || t->right[1] - t->left[1] < t->w )
116    {
117        t->left[0] = t->left[1] + i;
118        t->right[0] = t->right[1] + j;
119    }
120    else
121    {
122        t->left[0] = -10;
123        t->right[0] = g->w + 10;
124    }
125
126    if( t->w > g->w )
127    {
128        if( t->left[0] < 0 && t->right[0] < g->w - 2 )
129        {
130             t->left[0] = t->left[1] + 1;
131        }
132
133        if( t->left[0] > 1 && t->right[0] > g->w - 1 )
134        {
135             t->right[0] = t->right[1] - 1;
136        }
137    }
138    else
139    {
140        if( t->left[0] < 0 )
141        {
142            t->left[0] = t->left[1] + 1;
143        }
144
145        if( t->right[0] > g->w - 1 )
146        {
147            t->right[0] = t->right[1] - 1;
148        }
149    }
150}
151
152static void draw_wall( game *g, int *wall, int delta )
153{
154    int i;
155
156    gfx_color( RED );
157
158    for( i = 0; i < g->h ; i++ )
159    {
160        char *str;
161
162        if( wall[i] < -10 || wall[i] >= g->w + 10 )
163        {
164            continue;
165        }
166
167        if( wall[i] > wall[i+1] )
168        {
169            str = wall[i] > wall[i-1] ? ">##>" : "/##/";
170        }
171        else
172        {
173            str = wall[i] > wall[i-1] ? "\\##\\" : "<##<";
174        }
175
176        if( wall[i] == wall[i+1] + 2 )
177        {
178            gfx_goto( wall[i] - 1 + delta, i );
179            gfx_putchar( '_' );
180        }
181
182        gfx_goto( wall[i] + delta, i );
183        gfx_putstr( str );
184        if( wall[i] == wall[i+1] - 2 ) gfx_putchar( '_' );
185    }
186}
187
Note: See TracBrowser for help on using the repository browser.