ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/expand2x.C
Revision: 1.4
Committed: Thu Sep 14 22:34:02 2006 UTC (17 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.3: +1 -2 lines
Log Message:
indent

File Contents

# Content
1 /*
2 * Expands a layout by 2x in each dimension.
3 * H. S. Teoh
4 * --------------------------------------------------------------------------
5 * $Id: expand2x.C,v 1.3 2006-09-10 16:06:37 root Exp $
6 *
7 * ALGORITHM
8 *
9 * ... (TBW)
10 */
11
12 #include <stdlib.h> /* just in case */
13 #include <expand2x.h> /* use compiler to do sanity check */
14
15
16 /* PROTOTYPES */
17
18 static void expand_misc (char **newlayout, int i, int j, char **layout, int xsize, int ysize);
19 static void expand_wall (char **newlayout, int i, int j, char **layout, int xsize, int ysize);
20 static void expand_door (char **newlayout, int i, int j, char **layout, int xsize, int ysize);
21
22
23 /* FUNCTIONS */
24
25 char **
26 expand2x (char **layout, int xsize, int ysize)
27 {
28 int i, j;
29 int nxsize = xsize * 2 - 1;
30 int nysize = ysize * 2 - 1;
31
32 /* Allocate new layout */
33 char **newlayout = (char **) calloc (sizeof (char *), nxsize);
34
35 for (i = 0; i < nxsize; i++)
36 {
37 newlayout[i] = (char *) calloc (sizeof (char), nysize);
38 }
39
40 for (i = 0; i < xsize; i++)
41 {
42 for (j = 0; j < ysize; j++)
43 {
44 switch (layout[i][j])
45 {
46 case '#':
47 expand_wall (newlayout, i, j, layout, xsize, ysize);
48 break;
49 case 'D':
50 expand_door (newlayout, i, j, layout, xsize, ysize);
51 break;
52 default:
53 expand_misc (newlayout, i, j, layout, xsize, ysize);
54 }
55 }
56 }
57
58 /* Dump old layout */
59 for (i = 0; i < xsize; i++)
60 {
61 free (layout[i]);
62 }
63 free (layout);
64
65 return newlayout;
66 }
67
68 /* Copy the old tile X into the new one at location (i*2, j*2) and
69 * fill up the rest of the 2x2 result with \0:
70 * X ---> X \0
71 * \0 \0
72 */
73 static void
74 expand_misc (char **newlayout, int i, int j, char **layout, int xsize, int ysize)
75 {
76 newlayout[i * 2][j * 2] = layout[i][j];
77 /* (Note: no need to reset rest of 2x2 area to \0 because calloc does that
78 * for us.) */
79 }
80
81 /* Returns a bitmap that represents which squares on the right and bottom
82 * edges of a square (i,j) match the given character:
83 * 1 match on (i+1, j)
84 * 2 match on (i, j+1)
85 * 4 match on (i+1, j+1)
86 * and the possible combinations thereof.
87 */
88 static int
89 calc_pattern (char ch, char **layout, int i, int j, int xsize, int ysize)
90 {
91 int pattern = 0;
92
93 if (i + 1 < xsize && layout[i + 1][j] == ch)
94 pattern |= 1;
95
96 if (j + 1 < ysize)
97 {
98 if (layout[i][j + 1] == ch)
99 pattern |= 2;
100 if (i + 1 < xsize && layout[i + 1][j + 1] == ch)
101 pattern |= 4;
102 }
103
104 return pattern;
105 }
106
107 /* Expand a wall. This function will try to sensibly connect the resulting
108 * wall to adjacent wall squares, so that the result won't have disconnected
109 * walls.
110 */
111 static void
112 expand_wall (char **newlayout, int i, int j, char **layout, int xsize, int ysize)
113 {
114 int wall_pattern = calc_pattern ('#', layout, i, j, xsize, ysize);
115 int door_pattern = calc_pattern ('D', layout, i, j, xsize, ysize);
116 int both_pattern = wall_pattern | door_pattern;
117
118 newlayout[i * 2][j * 2] = '#';
119 if (i + 1 < xsize)
120 {
121 if (both_pattern & 1)
122 { /* join walls/doors to the right */
123
124 /* newlayout[i*2+1][j*2] = '#'; */
125 newlayout[i * 2 + 1][j * 2] = layout[i + 1][j];
126 }
127 }
128
129 if (j + 1 < ysize)
130 {
131 if (both_pattern & 2)
132 { /* join walls/doors to the bottom */
133
134 /* newlayout[i*2][j*2+1] = '#'; */
135 newlayout[i * 2][j * 2 + 1] = layout[i][j + 1];
136 }
137
138 if (wall_pattern == 7)
139 { /* if orig layout is a 2x2 wall block,
140 * we fill the result with walls. */
141 newlayout[i * 2 + 1][j * 2 + 1] = '#';
142 }
143 }
144 }
145
146 /* This function will try to sensibly connect doors so that they meet up with
147 * adjacent walls. Note that it will also presumptuously delete (ignore) doors
148 * that it doesn't know how to correctly expand.
149 */
150 static void
151 expand_door (char **newlayout, int i, int j, char **layout, int xsize, int ysize)
152 {
153 int wall_pattern = calc_pattern ('#', layout, i, j, xsize, ysize);
154 int door_pattern = calc_pattern ('D', layout, i, j, xsize, ysize);
155 int join_pattern;
156
157 /* Doors "like" to connect to walls more than other doors. If there is
158 * a wall and another door, this door will connect to the wall and
159 * disconnect from the other door. */
160 if (wall_pattern & 3)
161 {
162 join_pattern = wall_pattern;
163 }
164 else
165 {
166 join_pattern = door_pattern;
167 }
168
169 newlayout[i * 2][j * 2] = 'D';
170 if (i + 1 < xsize)
171 {
172 if (join_pattern & 1)
173 { /* there is a door/wall to the right */
174 newlayout[i * 2 + 1][j * 2] = 'D';
175 }
176 }
177
178 if (j + 1 < ysize)
179 {
180 if (join_pattern & 2)
181 { /* there is a door/wall below */
182 newlayout[i * 2][j * 2 + 1] = 'D';
183 }
184 }
185 }