Crossfire Server, Trunk  R20513
expand2x.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
21 #include <stdlib.h> /* just in case */
22 #include <expand2x.h> /* use compiler to do sanity check */
23 
24 
25 /* PROTOTYPES */
26 
27 static void expand_misc(char **newlayout, int i, int j, char **layout);
28 static void expand_wall(char **newlayout, int i, int j, char **layout, int xsize, int ysize);
29 static void expand_door(char **newlayout, int i, int j, char **layout, int xsize, int ysize);
30 
31 /* FUNCTIONS */
32 
43 char **expand2x(char **layout, int xsize, int ysize)
44 {
45  int i, j;
46  int nxsize = xsize*2-1;
47  int nysize = ysize*2-1;
48 
49  /* Allocate new layout */
50  char **newlayout = (char **)calloc(sizeof(char *), nxsize);
51  for (i = 0; i < nxsize; i++) {
52  newlayout[i] = (char *)calloc(sizeof(char), nysize);
53  }
54 
55  for (i = 0; i < xsize; i++) {
56  for (j = 0; j < ysize; j++) {
57  switch (layout[i][j]) {
58  case '#':
59  expand_wall(newlayout, i, j, layout, xsize, ysize);
60  break;
61 
62  case 'D':
63  expand_door(newlayout, i, j, layout, xsize, ysize);
64  break;
65 
66  default:
67  expand_misc(newlayout, i, j, layout);
68  }
69  }
70  }
71 
72  /* Dump old layout */
73  for (i = 0; i < xsize; i++) {
74  free(layout[i]);
75  }
76  free(layout);
77 
78  return newlayout;
79 }
80 
94 static void expand_misc(char **newlayout, int i, int j, char **layout)
95 {
96  newlayout[i*2][j*2] = layout[i][j];
97  /* (Note: no need to reset rest of 2x2 area to \0 because calloc does that
98  * for us.) */
99 }
100 
121 static int calc_pattern(char ch, char **layout, int i, int j, int xsize, int ysize)
122 {
123  int pattern = 0;
124 
125  if (i+1 < xsize && layout[i+1][j] == ch) {
126  pattern |= 1;
127  }
128 
129  if (j+1 < ysize) {
130  if (layout[i][j+1] == ch) {
131  pattern |= 2;
132  }
133  if (i+1 < xsize && layout[i+1][j+1] == ch) {
134  pattern |= 4;
135  }
136  }
137 
138  return pattern;
139 }
140 
156 static void expand_wall(char **newlayout, int i, int j, char **layout, int xsize, int ysize)
157 {
158  int wall_pattern = calc_pattern('#', layout, i, j, xsize, ysize);
159  int door_pattern = calc_pattern('D', layout, i, j, xsize, ysize);
160  int both_pattern = wall_pattern|door_pattern;
161 
162  newlayout[i*2][j*2] = '#';
163  if (i+1 < xsize) {
164  if (both_pattern&1) {
165  /* join walls/doors to the right */
166  newlayout[i*2+1][j*2] = layout[i+1][j];
167  }
168  }
169 
170  if (j+1 < ysize) {
171  if (both_pattern&2) {
172  /* join walls/doors to the bottom */
173  newlayout[i*2][j*2+1] = layout[i][j+1];
174  }
175 
176  if (wall_pattern == 7) {
177  /* if orig layout is a 2x2 wall block,
178  * we fill the result with walls. */
179  newlayout[i*2+1][j*2+1] = '#';
180  }
181  }
182 }
183 
199 static void expand_door(char **newlayout, int i, int j, char **layout, int xsize, int ysize)
200 {
201  int wall_pattern = calc_pattern('#', layout, i, j, xsize, ysize);
202  int door_pattern = calc_pattern('D', layout, i, j, xsize, ysize);
203  int join_pattern;
204 
205  /* Doors "like" to connect to walls more than other doors. If there is
206  * a wall and another door, this door will connect to the wall and
207  * disconnect from the other door. */
208  if (wall_pattern&3) {
209  join_pattern = wall_pattern;
210  } else {
211  join_pattern = door_pattern;
212  }
213 
214  newlayout[i*2][j*2] = 'D';
215  if (i+1 < xsize) {
216  if (join_pattern&1) {
217  /* there is a door/wall to the right */
218  newlayout[i*2+1][j*2] = 'D';
219  }
220  }
221 
222  if (j+1 < ysize) {
223  if (join_pattern&2) {
224  /* there is a door/wall below */
225  newlayout[i*2][j*2+1] = 'D';
226  }
227  }
228 }
static void expand_wall(char **newlayout, int i, int j, char **layout, int xsize, int ysize)
Expand a wall.
Definition: expand2x.c:156
static int calc_pattern(char ch, char **layout, int i, int j, int xsize, int ysize)
Returns a bitmap that represents which squares on the right and bottom edges of a square (i...
Definition: expand2x.c:121
char ** expand2x(char **layout, int xsize, int ysize)
Expands the layout be a factor 2.
Definition: expand2x.c:43
static void expand_door(char **newlayout, int i, int j, char **layout, int xsize, int ysize)
Expand a door.
Definition: expand2x.c:199
Expands a layout by 2x in each dimension.
static void expand_misc(char **newlayout, int i, int j, char **layout)
Copy the old tile X into the new one at location (i*2, j*2) and fill up the rest of the 2x2 result wi...
Definition: expand2x.c:94
Definition: main.c:88