/* * ttyvaders Textmode shoot'em up * Copyright (c) 2002 Sam Hocevar * All Rights Reserved * * $Id$ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include #include "common.h" /* Init tunnel */ tunnel * create_tunnel(game *g, int w, int h) { int i; tunnel *t = malloc(sizeof(tunnel)); if(t == NULL) exit(1); t->left = malloc(h*sizeof(int)); if(t->left == NULL) exit(1); t->right = malloc(h*sizeof(int)); if(t->right == NULL) exit(1); t->w = w; t->h = h; if(t->w >= g->w) { for(i = 0; i < g->h; i++) { t->left[i] = -10; t->right[i] = g->w + 10; } } else { t->left[0] = (g->w - w) / 2; t->right[0] = (g->w + w) / 2; /* Yeah, sub-efficient, but less code to do :-) */ for(i = 0; i < g->h; i++) { update_tunnel(g, t); } } return t; } void free_tunnel(tunnel *t) { free(t->left); free(t->right); free(t); } void draw_tunnel(game *g, tunnel *t) { int i, j; char c; caca_set_color(EE_GREEN); /* Left border */ for(i = 0; i < g->h ; i++) { if(t->left[i] <= -10) continue; if(i + 1 == g->h || t->left[i] > t->left[i+1]) c = (i == 0 || t->left[i] > t->left[i-1]) ? '>' : '/'; else c = (i == 0 || t->left[i] > t->left[i-1]) ? '\\' : '<'; caca_putchar(t->left[i] + 1, i, c); if(i + 1 < g->h) for(j = 1; j < t->left[i+1] - t->left[i]; j++) caca_putchar(t->left[i] + j + 1, i, '_'); } /* Right border */ for(i = 0; i < g->h ; i++) { if(t->right[i] >= g->w + 10) continue; if(i + 1 == g->h || t->right[i] > t->right[i+1]) c = (i == 0 || t->right[i] > t->right[i-1]) ? '>' : '/'; else c = (i == 0 || t->right[i] > t->right[i-1]) ? '\\' : '<'; if(i + 1 < g->h) for(j = 1; j < t->right[i] - t->right[i+1]; j++) caca_putchar(t->right[i+1] + j - 1, i, '_'); caca_putchar(t->right[i] - 1, i, c); } caca_set_color(EE_RED); /* Left concrete */ for(i = 0; i < g->h ; i++) for(j = 0 ; j <= t->left[i]; j++) caca_putchar(j, i, '#'); /* Right concrete */ for(i = 0; i < g->h ; i++) for(j = t->right[i] ; j < g->w ; j++) caca_putchar(j, i, '#'); } void update_tunnel(game *g, tunnel *t) { static int const delta[] = { -3, -2, -1, 1, 2, 3 }; int i,j,k; /* Slide tunnel one block vertically */ for(i = t->h - 1; i--;) { t->left[i+1] = t->left[i]; t->right[i+1] = t->right[i]; } /* Generate new values */ i = delta[caca_rand(0,5)]; j = delta[caca_rand(0,5)]; /* Check in which direction we need to alter tunnel */ if(t->right[1] - t->left[1] < t->w) { /* Not wide enough, make sure i <= j */ if(i > j) { k = j; j = i; i = k; } } else if(t->right[1] - t->left[1] - 2 > t->w) { /* Too wide, make sure i >= j */ if(i < j) { k = j; j = i; i = k; } } else { /* No need to mess with i and j: width is OK */ } /* If width doesn't exceed game size, update coords */ if(t->w <= g->w || t->right[1] - t->left[1] < t->w) { t->left[0] = t->left[1] + i; t->right[0] = t->right[1] + j; } else { t->left[0] = -10; t->right[0] = g->w + 10; } if(t->w > g->w) { if(t->left[0] < 0 && t->right[0] < g->w - 2) { t->left[0] = t->left[1] + 1; } if(t->left[0] > 1 && t->right[0] > g->w - 1) { t->right[0] = t->right[1] - 1; } } else { if(t->left[0] < 0) { t->left[0] = t->left[1] + 1; } if(t->right[0] > g->w - 1) { t->right[0] = t->right[1] - 1; } } }