source: ttyvaders/trunk/src/tunnel.c @ 56

Last change on this file since 56 was 56, checked in by Sam Hocevar, 18 years ago
  • cosmetic change: reworked draw_tunnel.
File size: 5.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.8 2002/12/23 12:47:36 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 "config.h"
24
25#include <stdlib.h>
26
27#include "common.h"
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    int i, j;
72    char c;
73
74    gfx_color( GREEN );
75
76    /* Left border */
77    for( i = 0; i < g->h ; i++ )
78    {
79        if( t->left[i] <= -10 )
80        {
81            continue;
82        }
83
84        if( i + 1 == g->h || t->left[i] > t->left[i+1] )
85        {
86            c = ( i == 0 || t->left[i] > t->left[i-1] ) ? '>' : '/';
87        }
88        else
89        {
90            c = ( i == 0 || t->left[i] > t->left[i-1] ) ? '\\' : '<';
91        }
92
93        gfx_goto( t->left[i] + 1, i );
94        gfx_putchar( c );
95
96        if( i + 1 < g->h )
97        {
98            for( j = 1; j < t->left[i+1] - t->left[i]; j++ )
99            {
100                gfx_goto( t->left[i] + j + 1, i );
101                gfx_putchar( '_' );
102            }
103        }
104    }
105
106    /* Right border */
107    for( i = 0; i < g->h ; i++ )
108    {
109        if( t->right[i] >= g->w + 10 )
110        {
111            continue;
112        }
113
114        if( i + 1 == g->h || t->right[i] > t->right[i+1] )
115        {
116            c = ( i == 0 || t->right[i] > t->right[i-1] ) ? '>' : '/';
117        }
118        else
119        {
120            c = ( i == 0 || t->right[i] > t->right[i-1] ) ? '\\' : '<';
121        }
122
123        if( i + 1 < g->h )
124        {
125            for( j = 1; j < t->right[i] - t->right[i+1]; j++ )
126            {
127                gfx_goto( t->right[i+1] + j - 1, i );
128                gfx_putchar( '_' );
129            }
130        }
131
132        gfx_goto( t->right[i] - 1, i );
133        gfx_putchar( c );
134    }
135
136    gfx_color( RED );
137
138    /* Left concrete */
139    for( i = 0; i < g->h ; i++ )
140    {
141        for( j = 0 ; j <= t->left[i]; j++ )
142        {
143            gfx_goto( j, i );
144            gfx_putchar( '#' );
145        }
146    }
147
148    /* Right concrete */
149    for( i = 0; i < g->h ; i++ )
150    {
151        for( j = t->right[i] ; j < g->w ; j++ )
152        {
153            gfx_goto( j, i );
154            gfx_putchar( '#' );
155        }
156    }
157}
158
159void update_tunnel( game *g, tunnel *t )
160{
161    static int const delta[] = { -3, -2, -1, 1, 2, 3 };
162    int i,j,k;
163
164    /* Slide tunnel one block vertically */
165    for( i = t->h - 1; i--; )
166    {
167        t->left[i+1] = t->left[i];
168        t->right[i+1] = t->right[i];
169    }
170
171    /* Generate new values */
172    i = delta[GET_RAND(0,6)];
173    j = delta[GET_RAND(0,6)];
174
175    /* Check in which direction we need to alter tunnel */
176    if( t->right[1] - t->left[1] < t->w )
177    {
178        /* Not wide enough, make sure i <= j */
179        if( i > j )
180        {
181            k = j; j = i; i = k;
182        }
183    }
184    else if( t->right[1] - t->left[1] - 2 > t->w )
185    {
186        /* Too wide, make sure i >= j */
187        if( i < j )
188        {
189            k = j; j = i; i = k;
190        }
191    }
192    else
193    {
194        /* No need to mess with i and j: width is OK */
195    }
196
197    /* If width doesn't exceed game size, update coords */
198    if( t->w <= g->w || t->right[1] - t->left[1] < t->w )
199    {
200        t->left[0] = t->left[1] + i;
201        t->right[0] = t->right[1] + j;
202    }
203    else
204    {
205        t->left[0] = -10;
206        t->right[0] = g->w + 10;
207    }
208
209    if( t->w > g->w )
210    {
211        if( t->left[0] < 0 && t->right[0] < g->w - 2 )
212        {
213             t->left[0] = t->left[1] + 1;
214        }
215
216        if( t->left[0] > 1 && t->right[0] > g->w - 1 )
217        {
218             t->right[0] = t->right[1] - 1;
219        }
220    }
221    else
222    {
223        if( t->left[0] < 0 )
224        {
225            t->left[0] = t->left[1] + 1;
226        }
227
228        if( t->right[0] > g->w - 1 )
229        {
230            t->right[0] = t->right[1] - 1;
231        }
232    }
233}
234
Note: See TracBrowser for help on using the repository browser.