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

Last change on this file since 2990 was 2990, checked in by Sam Hocevar, 12 years ago

Port ttyvaders to the unified libcaca 0.99.beta15 API.

  • Property svn:keywords set to Id
File size: 4.4 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 2990 2008-10-18 21:42:24Z sam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15#include "config.h"
16
17#include <stdlib.h>
18
19#include "common.h"
20
21/* Init tunnel */
22tunnel * create_tunnel(game *g, int w, int h)
23{
24    int i;
25    tunnel *t = malloc(sizeof(tunnel));
26    if(t == NULL)
27        exit(1);
28
29    t->left = malloc(h*sizeof(int));
30    if(t->left == NULL)
31        exit(1);
32    t->right = malloc(h*sizeof(int));
33    if(t->right == NULL)
34        exit(1);
35    t->w = w;
36    t->h = h;
37
38    if(t->w >= g->w)
39    {
40        for(i = 0; i < g->h; i++)
41        {
42            t->left[i] = -10;
43            t->right[i] = g->w + 10;
44        }
45    }
46    else
47    {
48        t->left[0] = (g->w - w) / 2;
49        t->right[0] = (g->w + w) / 2;
50        /* Yeah, sub-efficient, but less code to do :-) */
51        for(i = 0; i < g->h; i++)
52        {
53            update_tunnel(g, t);
54        }
55    }
56
57    return t;
58}
59
60void free_tunnel(tunnel *t)
61{
62    free(t->left);
63    free(t->right);
64    free(t);
65}
66
67void draw_tunnel(game *g, tunnel *t)
68{
69    int i, j;
70    char c;
71
72    caca_set_color(g->cv, CACA_COLOR_RED, CACA_COLOR_BLACK);
73
74    /* Left border */
75    for(i = 0; i < g->h ; i++)
76    {
77        if(t->left[i] <= -10)
78            continue;
79
80        if(i + 1 == g->h || t->left[i] > t->left[i+1])
81            c = (i == 0 || t->left[i] > t->left[i-1]) ? '>' : '/';
82        else
83            c = (i == 0 || t->left[i] > t->left[i-1]) ? '\\' : '<';
84
85        caca_putchar(g->cv, t->left[i] + 1, i, c);
86
87        if(i + 1 < g->h)
88            for(j = 1; j < t->left[i+1] - t->left[i]; j++)
89                caca_putchar(g->cv, t->left[i] + j + 1, i, '_');
90    }
91
92    /* Right border */
93    for(i = 0; i < g->h ; i++)
94    {
95        if(t->right[i] >= g->w + 10)
96            continue;
97
98        if(i + 1 == g->h || t->right[i] > t->right[i+1])
99            c = (i == 0 || t->right[i] > t->right[i-1]) ? '>' : '/';
100        else
101            c = (i == 0 || t->right[i] > t->right[i-1]) ? '\\' : '<';
102
103        if(i + 1 < g->h)
104            for(j = 1; j < t->right[i] - t->right[i+1]; j++)
105                caca_putchar(g->cv, t->right[i+1] + j - 1, i, '_');
106
107        caca_putchar(g->cv, t->right[i] - 1, i, c);
108    }
109
110    caca_set_color(g->cv, CACA_COLOR_LIGHTRED, CACA_COLOR_RED);
111
112    /* Left concrete */
113    for(i = 0; i < g->h ; i++)
114        for(j = 0 ; j <= t->left[i]; j++)
115            caca_putchar(g->cv, j, i, '#');
116
117    /* Right concrete */
118    for(i = 0; i < g->h ; i++)
119        for(j = t->right[i] ; j < g->w ; j++)
120            caca_putchar(g->cv, j, i, '#');
121}
122
123void update_tunnel(game *g, tunnel *t)
124{
125    static int const delta[] = { -3, -2, -1, 1, 2, 3 };
126    int i,j,k;
127
128    /* Slide tunnel one block vertically */
129    for(i = t->h - 1; i--;)
130    {
131        t->left[i+1] = t->left[i];
132        t->right[i+1] = t->right[i];
133    }
134
135    /* Generate new values */
136    i = delta[caca_rand(0,5)];
137    j = delta[caca_rand(0,5)];
138
139    /* Check in which direction we need to alter tunnel */
140    if(t->right[1] - t->left[1] < t->w)
141    {
142        /* Not wide enough, make sure i <= j */
143        if(i > j)
144        {
145            k = j; j = i; i = k;
146        }
147    }
148    else if(t->right[1] - t->left[1] - 2 > t->w)
149    {
150        /* Too wide, make sure i >= j */
151        if(i < j)
152        {
153            k = j; j = i; i = k;
154        }
155    }
156    else
157    {
158        /* No need to mess with i and j: width is OK */
159    }
160
161    /* If width doesn't exceed game size, update coords */
162    if(t->w <= g->w || t->right[1] - t->left[1] < t->w)
163    {
164        t->left[0] = t->left[1] + i;
165        t->right[0] = t->right[1] + j;
166    }
167    else
168    {
169        t->left[0] = -10;
170        t->right[0] = g->w + 10;
171    }
172
173    if(t->w > g->w)
174    {
175        if(t->left[0] < 0 && t->right[0] < g->w - 2)
176        {
177             t->left[0] = t->left[1] + 1;
178        }
179
180        if(t->left[0] > 1 && t->right[0] > g->w - 1)
181        {
182             t->right[0] = t->right[1] - 1;
183        }
184    }
185    else
186    {
187        if(t->left[0] < 0)
188        {
189            t->left[0] = t->left[1] + 1;
190        }
191
192        if(t->right[0] > g->w - 1)
193        {
194            t->right[0] = t->right[1] - 1;
195        }
196    }
197}
198
Note: See TracBrowser for help on using the repository browser.