ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/expand2x.C
Revision: 1.6
Committed: Fri Apr 11 21:09:53 2008 UTC (16 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.5: +27 -54 lines
Log Message:
*** empty log message ***

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