ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/expand2x.C
Revision: 1.5
Committed: Sun Dec 31 19:02:24 2006 UTC (17 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_4, rel-2_2, rel-2_3, rel-2_0, rel-2_1, rel-2_32, rel-2_43, rel-2_42, rel-2_41
Changes since 1.4: +10 -9 lines
Log Message:
reindent, minor changes

File Contents

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