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, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.3: +1 -2 lines
Log Message:
indent

File Contents

# User Rev Content
1 elmex 1.1 /*
2     * Expands a layout by 2x in each dimension.
3     * H. S. Teoh
4     * --------------------------------------------------------------------------
5 root 1.4 * $Id: expand2x.C,v 1.3 2006-09-10 16:06:37 root Exp $
6 elmex 1.1 *
7     * ALGORITHM
8     *
9     * ... (TBW)
10     */
11    
12 root 1.3 #include <stdlib.h> /* just in case */
13     #include <expand2x.h> /* use compiler to do sanity check */
14 elmex 1.1
15    
16     /* PROTOTYPES */
17    
18 root 1.3 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 elmex 1.1
22    
23     /* FUNCTIONS */
24    
25 root 1.3 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 elmex 1.1
32     /* Allocate new layout */
33 root 1.3 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 elmex 1.1 }
57    
58     /* Dump old layout */
59 root 1.3 for (i = 0; i < xsize; i++)
60     {
61     free (layout[i]);
62     }
63     free (layout);
64 elmex 1.1
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 root 1.3 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 elmex 1.1 /* (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 root 1.3 static int
89     calc_pattern (char ch, char **layout, int i, int j, int xsize, int ysize)
90     {
91 elmex 1.1 int pattern = 0;
92    
93 root 1.3 if (i + 1 < xsize && layout[i + 1][j] == ch)
94 elmex 1.1 pattern |= 1;
95    
96 root 1.3 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 elmex 1.1
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 root 1.3 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 elmex 1.1 int both_pattern = wall_pattern | door_pattern;
117    
118 root 1.3 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 elmex 1.1 /* newlayout[i*2+1][j*2] = '#'; */
125 root 1.3 newlayout[i * 2 + 1][j * 2] = layout[i + 1][j];
126     }
127 elmex 1.1 }
128    
129 root 1.3 if (j + 1 < ysize)
130     {
131     if (both_pattern & 2)
132     { /* join walls/doors to the bottom */
133    
134 elmex 1.1 /* newlayout[i*2][j*2+1] = '#'; */
135 root 1.3 newlayout[i * 2][j * 2 + 1] = layout[i][j + 1];
136     }
137 elmex 1.1
138 root 1.3 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 elmex 1.1 }
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 root 1.3 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 elmex 1.1 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 root 1.3 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 elmex 1.1 }
185     }