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

# User Rev Content
1 root 1.5
2 elmex 1.1 /*
3     * Expands a layout by 2x in each dimension.
4     * H. S. Teoh
5     * --------------------------------------------------------------------------
6 root 1.6 * $Id: expand2x.C,v 1.5 2006-12-31 19:02:24 root Exp $
7 elmex 1.1 *
8     * ALGORITHM
9     *
10     * ... (TBW)
11     */
12    
13 root 1.6 #include "global.h"
14     #include "random_map.h"
15     #include "rproto.h"
16 elmex 1.1
17     /* PROTOTYPES */
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     /* FUNCTIONS */
23 root 1.6 Maze
24     expand2x (Maze layout, int xsize, int ysize)
25 root 1.3 {
26     int i, j;
27     int nxsize = xsize * 2 - 1;
28     int nysize = ysize * 2 - 1;
29 elmex 1.1
30 root 1.6 Maze newlayout (nxsize, nysize);
31 root 1.3
32     for (i = 0; i < xsize; i++)
33 root 1.6 for (j = 0; j < ysize; j++)
34     switch (layout[i][j])
35 root 1.3 {
36 root 1.6 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 root 1.3 }
45 elmex 1.1
46 root 1.6 layout.free ();
47 elmex 1.1
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 root 1.3 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 elmex 1.1 /* (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 root 1.3 static int
72     calc_pattern (char ch, char **layout, int i, int j, int xsize, int ysize)
73     {
74 elmex 1.1 int pattern = 0;
75    
76 root 1.3 if (i + 1 < xsize && layout[i + 1][j] == ch)
77 elmex 1.1 pattern |= 1;
78    
79 root 1.3 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 elmex 1.1
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 root 1.3 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 elmex 1.1 int both_pattern = wall_pattern | door_pattern;
100    
101 root 1.3 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 elmex 1.1 /* newlayout[i*2+1][j*2] = '#'; */
108 root 1.3 newlayout[i * 2 + 1][j * 2] = layout[i + 1][j];
109     }
110 elmex 1.1 }
111    
112 root 1.3 if (j + 1 < ysize)
113     {
114     if (both_pattern & 2)
115     { /* join walls/doors to the bottom */
116    
117 elmex 1.1 /* newlayout[i*2][j*2+1] = '#'; */
118 root 1.3 newlayout[i * 2][j * 2 + 1] = layout[i][j + 1];
119     }
120 elmex 1.1
121 root 1.3 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 elmex 1.1 }
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 root 1.3 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 elmex 1.1 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 root 1.3 if (wall_pattern & 3)
144 root 1.6 join_pattern = wall_pattern;
145 root 1.3 else
146 root 1.6 join_pattern = door_pattern;
147 root 1.3
148     newlayout[i * 2][j * 2] = 'D';
149 root 1.6
150 root 1.3 if (i + 1 < xsize)
151 root 1.6 if (join_pattern & 1)
152     /* there is a door/wall to the right */
153     newlayout[i * 2 + 1][j * 2] = 'D';
154 root 1.3
155     if (j + 1 < ysize)
156 root 1.6 if (join_pattern & 2)
157     /* there is a door/wall below */
158     newlayout[i * 2][j * 2 + 1] = 'D';
159 elmex 1.1 }