ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/expand2x.C
Revision: 1.3
Committed: Sun Sep 10 16:06:37 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.2: +110 -86 lines
Log Message:
indent

File Contents

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