ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/expand2x.C
(Generate patch)

Comparing deliantra/server/random_maps/expand2x.C (file contents):
Revision 1.3 by root, Sun Sep 10 16:06:37 2006 UTC vs.
Revision 1.9 by root, Sat Nov 7 18:32:45 2009 UTC

1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 *
4 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) Crossfire Development Team (restored, original file without copyright notice)
6 *
7 * Deliantra is free software: you can redistribute it and/or modify it under
8 * the terms of the Affero GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the Affero GNU General Public License
18 * and the GNU General Public License along with this program. If not, see
19 * <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <support@deliantra.net>
22 */
1 23
2/* 24/*
3 * Expands a layout by 2x in each dimension. 25 * Expands a layout by 2x in each dimension.
4 * H. S. Teoh 26 * H. S. Teoh
5 * -------------------------------------------------------------------------- 27 * --------------------------------------------------------------------------
6 * $Id: expand2x.C,v 1.3 2006/09/10 16:06:37 root Exp $ 28 * $Id: expand2x.C,v 1.9 2009/11/07 18:32:45 root Exp $
7 * 29 *
8 * ALGORITHM 30 * ALGORITHM
9 * 31 *
10 * ... (TBW) 32 * ... (TBW)
11 */ 33 */
12 34
13#include <stdlib.h> /* just in case */ 35#include "global.h"
14#include <expand2x.h> /* use compiler to do sanity check */ 36#include "random_map.h"
15 37#include "rproto.h"
16
17/* PROTOTYPES */
18
19static void expand_misc (char **newlayout, int i, int j, char **layout, int xsize, int ysize);
20static void expand_wall (char **newlayout, int i, int j, char **layout, int xsize, int ysize);
21static void expand_door (char **newlayout, int i, int j, char **layout, int xsize, int ysize);
22
23
24/* FUNCTIONS */
25
26char **
27expand2x (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 38
69/* Copy the old tile X into the new one at location (i*2, j*2) and 39/* 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: 40 * fill up the rest of the 2x2 result with \0:
71 * X ---> X \0 41 * X ---> X \0
72 * \0 \0 42 * \0 \0
73 */ 43 */
74static void 44static void
75expand_misc (char **newlayout, int i, int j, char **layout, int xsize, int ysize) 45expand_misc (Layout newlayout, int i, int j, Layout layout)
76{ 46{
77 newlayout[i * 2][j * 2] = layout[i][j]; 47 newlayout[i * 2][j * 2] = layout[i][j];
78 /* (Note: no need to reset rest of 2x2 area to \0 because calloc does that 48 /* (Note: no need to reset rest of 2x2 area to \0 because calloc does that
79 * for us.) */ 49 * for us.) */
80} 50}
85 * 2 match on (i, j+1) 55 * 2 match on (i, j+1)
86 * 4 match on (i+1, j+1) 56 * 4 match on (i+1, j+1)
87 * and the possible combinations thereof. 57 * and the possible combinations thereof.
88 */ 58 */
89static int 59static int
90calc_pattern (char ch, char **layout, int i, int j, int xsize, int ysize) 60calc_pattern (char ch, Layout layout, int i, int j)
91{ 61{
92 int pattern = 0; 62 int pattern = 0;
93 63
94 if (i + 1 < xsize && layout[i + 1][j] == ch) 64 if (i + 1 < layout->w && layout[i + 1][j] == ch)
95 pattern |= 1; 65 pattern |= 1;
96 66
97 if (j + 1 < ysize) 67 if (j + 1 < layout->h)
98 { 68 {
99 if (layout[i][j + 1] == ch) 69 if (layout[i][j + 1] == ch)
100 pattern |= 2; 70 pattern |= 2;
71
101 if (i + 1 < xsize && layout[i + 1][j + 1] == ch) 72 if (i + 1 < layout->w && layout[i + 1][j + 1] == ch)
102 pattern |= 4; 73 pattern |= 4;
103 } 74 }
104 75
105 return pattern; 76 return pattern;
106} 77}
108/* Expand a wall. This function will try to sensibly connect the resulting 79/* 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 80 * wall to adjacent wall squares, so that the result won't have disconnected
110 * walls. 81 * walls.
111 */ 82 */
112static void 83static void
113expand_wall (char **newlayout, int i, int j, char **layout, int xsize, int ysize) 84expand_wall (Layout newlayout, int i, int j, Layout layout)
114{ 85{
115 int wall_pattern = calc_pattern ('#', layout, i, j, xsize, ysize); 86 int wall_pattern = calc_pattern ('#', layout, i, j);
116 int door_pattern = calc_pattern ('D', layout, i, j, xsize, ysize); 87 int door_pattern = calc_pattern ('D', layout, i, j);
117 int both_pattern = wall_pattern | door_pattern; 88 int both_pattern = wall_pattern | door_pattern;
118 89
119 newlayout[i * 2][j * 2] = '#'; 90 newlayout[i * 2][j * 2] = '#';
120 if (i + 1 < xsize) 91
92 if (i + 1 < layout->w)
121 { 93 {
122 if (both_pattern & 1) 94 if (both_pattern & 1)
123 { /* join walls/doors to the right */ 95 { /* join walls/doors to the right */
124
125/* newlayout[i*2+1][j*2] = '#'; */ 96/* newlayout[i*2+1][j*2] = '#'; */
126 newlayout[i * 2 + 1][j * 2] = layout[i + 1][j]; 97 newlayout[i * 2 + 1][j * 2] = layout[i + 1][j];
127 } 98 }
128 } 99 }
129 100
130 if (j + 1 < ysize) 101 if (j + 1 < layout->h)
131 { 102 {
132 if (both_pattern & 2) 103 if (both_pattern & 2)
133 { /* join walls/doors to the bottom */ 104 { /* join walls/doors to the bottom */
134
135/* newlayout[i*2][j*2+1] = '#'; */ 105/* newlayout[i*2][j*2+1] = '#'; */
136 newlayout[i * 2][j * 2 + 1] = layout[i][j + 1]; 106 newlayout[i * 2][j * 2 + 1] = layout[i][j + 1];
137 } 107 }
138 108
139 if (wall_pattern == 7) 109 if (wall_pattern == 7)
147/* This function will try to sensibly connect doors so that they meet up with 117/* 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 118 * adjacent walls. Note that it will also presumptuously delete (ignore) doors
149 * that it doesn't know how to correctly expand. 119 * that it doesn't know how to correctly expand.
150 */ 120 */
151static void 121static void
152expand_door (char **newlayout, int i, int j, char **layout, int xsize, int ysize) 122expand_door (Layout newlayout, int i, int j, Layout layout)
153{ 123{
154 int wall_pattern = calc_pattern ('#', layout, i, j, xsize, ysize); 124 int wall_pattern = calc_pattern ('#', layout, i, j);
155 int door_pattern = calc_pattern ('D', layout, i, j, xsize, ysize); 125 int door_pattern = calc_pattern ('D', layout, i, j);
156 int join_pattern; 126 int join_pattern;
157 127
158 /* Doors "like" to connect to walls more than other doors. If there is 128 /* 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 129 * a wall and another door, this door will connect to the wall and
160 * disconnect from the other door. */ 130 * disconnect from the other door. */
161 if (wall_pattern & 3) 131 if (wall_pattern & 3)
162 {
163 join_pattern = wall_pattern; 132 join_pattern = wall_pattern;
164 }
165 else 133 else
166 {
167 join_pattern = door_pattern; 134 join_pattern = door_pattern;
168 }
169 135
170 newlayout[i * 2][j * 2] = 'D'; 136 newlayout[i * 2][j * 2] = 'D';
171 if (i + 1 < xsize) 137
172 { 138 if (i + 1 < layout->w)
173 if (join_pattern & 1) 139 if (join_pattern & 1)
174 { /* there is a door/wall to the right */ 140 /* there is a door/wall to the right */
175 newlayout[i * 2 + 1][j * 2] = 'D'; 141 newlayout[i * 2 + 1][j * 2] = 'D';
142
143 if (j + 1 < layout->h)
144 if (join_pattern & 2)
145 /* there is a door/wall below */
146 newlayout[i * 2][j * 2 + 1] = 'D';
147}
148
149void
150expand2x (Layout layout)
151{
152 Layout newlayout (layout->w * 2 - 1, layout->h * 2 - 1);
153 newlayout->clear ();
154
155 for (int i = 0; i < layout->w; i++)
156 for (int j = 0; j < layout->h; j++)
157 switch (layout[i][j])
158 {
159 case '#': expand_wall (newlayout, i, j, layout); break;
160 case 'D': expand_door (newlayout, i, j, layout); break;
161 default: expand_misc (newlayout, i, j, layout); break;
176 } 162 }
177 }
178 163
179 if (j + 1 < ysize) 164 layout.swap (newlayout);
180 { 165 newlayout.free ();
181 if (join_pattern & 2)
182 { /* there is a door/wall below */
183 newlayout[i * 2][j * 2 + 1] = 'D';
184 }
185 }
186} 166}
167

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines