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.2 by root, Tue Aug 29 08:01:36 2006 UTC vs.
Revision 1.10 by root, Thu Jul 1 01:22:44 2010 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 */
23
1/* 24/*
2 * Expands a layout by 2x in each dimension. 25 * Expands a layout by 2x in each dimension.
3 * H. S. Teoh 26 * H. S. Teoh
4 * -------------------------------------------------------------------------- 27 * --------------------------------------------------------------------------
5 * $Id: expand2x.C,v 1.2 2006/08/29 08:01:36 root Exp $ 28 * $Id: expand2x.C,v 1.10 2010/07/01 01:22:44 root Exp $
6 * 29 *
7 * ALGORITHM 30 * ALGORITHM
8 * 31 *
9 * ... (TBW) 32 * ... (TBW)
10 */ 33 */
11 34
12#include <stdlib.h> /* just in case */ 35#include "global.h"
13#include <expand2x.h> /* use compiler to do sanity check */ 36#include "random_map.h"
14 37#include "rproto.h"
15
16/* PROTOTYPES */
17
18static void expand_misc(char **newlayout, int i, int j, char **layout,
19 int xsize, int ysize);
20static void expand_wall(char **newlayout, int i, int j, char **layout,
21 int xsize, int ysize);
22static void expand_door(char **newlayout, int i, int j, char **layout,
23 int xsize, int ysize);
24
25
26/* FUNCTIONS */
27
28char **expand2x(char **layout, int xsize, int ysize) {
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 for (i=0; i<nxsize; i++) {
36 newlayout[i] = (char *) calloc(sizeof(char), nysize);
37 }
38
39 for (i=0; i<xsize; i++) {
40 for (j=0; j<ysize; j++) {
41 switch(layout[i][j]) {
42 case '#':
43 expand_wall(newlayout, i,j, layout, xsize, ysize);
44 break;
45 case 'D':
46 expand_door(newlayout, i,j, layout, xsize, ysize);
47 break;
48 default:
49 expand_misc(newlayout, i,j, layout, xsize, ysize);
50 }
51 }
52 }
53
54 /* Dump old layout */
55 for (i=0; i<xsize; i++) {
56 free(layout[i]);
57 }
58 free(layout);
59
60 return newlayout;
61}
62 38
63/* 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
64 * fill up the rest of the 2x2 result with \0: 40 * fill up the rest of the 2x2 result with \0:
65 * X ---> X \0 41 * X ---> X \0
66 * \0 \0 42 * \0 \0
67 */ 43 */
68static void expand_misc(char **newlayout, int i, int j, char **layout, 44static void
69 int xsize, int ysize) { 45expand_misc (Layout &newlayout, int i, int j, Layout &layout)
46{
70 newlayout[i*2][j*2] = layout[i][j]; 47 newlayout[i * 2][j * 2] = layout[i][j];
71 /* (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
72 * for us.) */ 49 * for us.) */
73} 50}
74 51
75/* Returns a bitmap that represents which squares on the right and bottom 52/* Returns a bitmap that represents which squares on the right and bottom
77 * 1 match on (i+1, j) 54 * 1 match on (i+1, j)
78 * 2 match on (i, j+1) 55 * 2 match on (i, j+1)
79 * 4 match on (i+1, j+1) 56 * 4 match on (i+1, j+1)
80 * and the possible combinations thereof. 57 * and the possible combinations thereof.
81 */ 58 */
59static int
82static int calc_pattern(char ch, char **layout, int i, int j, 60calc_pattern (char ch, Layout &layout, int i, int j)
83 int xsize, int ysize) { 61{
84 int pattern = 0; 62 int pattern = 0;
85 63
86 if (i+1<xsize && layout[i+1][j]==ch) 64 if (i + 1 < layout.w && layout[i + 1][j] == ch)
87 pattern |= 1; 65 pattern |= 1;
88 66
89 if (j+1<ysize) { 67 if (j + 1 < layout.h)
68 {
90 if (layout[i][j+1]==ch) 69 if (layout[i][j + 1] == ch)
91 pattern |= 2; 70 pattern |= 2;
92 if (i+1<xsize && layout[i+1][j+1]==ch) 71
72 if (i + 1 < layout.w && layout[i + 1][j + 1] == ch)
93 pattern |= 4; 73 pattern |= 4;
94 } 74 }
95 75
96 return pattern; 76 return pattern;
97} 77}
98 78
99/* 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
100 * 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
101 * walls. 81 * walls.
102 */ 82 */
103static void expand_wall(char **newlayout, int i, int j, char **layout, 83static void
104 int xsize, int ysize) { 84expand_wall (Layout &newlayout, int i, int j, Layout &layout)
85{
105 int wall_pattern = calc_pattern('#', layout, i, j, xsize, ysize); 86 int wall_pattern = calc_pattern ('#', layout, i, j);
106 int door_pattern = calc_pattern('D', layout, i, j, xsize, ysize); 87 int door_pattern = calc_pattern ('D', layout, i, j);
107 int both_pattern = wall_pattern | door_pattern; 88 int both_pattern = wall_pattern | door_pattern;
108 89
109 newlayout[i*2][j*2] = '#'; 90 newlayout[i * 2][j * 2] = '#';
110 if (i+1 < xsize) { 91
111 if (both_pattern & 1) { /* join walls/doors to the right */ 92 if (i + 1 < layout.w)
93 {
94 if (both_pattern & 1)
95 { /* join walls/doors to the right */
112/* newlayout[i*2+1][j*2] = '#'; */ 96/* newlayout[i*2+1][j*2] = '#'; */
113 newlayout[i*2+1][j*2] = layout[i+1][j]; 97 newlayout[i * 2 + 1][j * 2] = layout[i + 1][j];
114 } 98 }
115 }
116
117 if (j+1 < ysize) {
118 if (both_pattern & 2) { /* join walls/doors to the bottom */
119/* newlayout[i*2][j*2+1] = '#'; */
120 newlayout[i*2][j*2+1] = layout[i][j+1];
121 } 99 }
122 100
123 if (wall_pattern==7) { /* if orig layout is a 2x2 wall block, 101 if (j + 1 < layout.h)
102 {
103 if (both_pattern & 2)
104 { /* join walls/doors to the bottom */
105/* newlayout[i*2][j*2+1] = '#'; */
106 newlayout[i * 2][j * 2 + 1] = layout[i][j + 1];
107 }
108
109 if (wall_pattern == 7)
110 { /* if orig layout is a 2x2 wall block,
124 * we fill the result with walls. */ 111 * we fill the result with walls. */
125 newlayout[i*2+1][j*2+1] = '#'; 112 newlayout[i * 2 + 1][j * 2 + 1] = '#';
113 }
126 } 114 }
127 }
128} 115}
129 116
130/* 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
131 * adjacent walls. Note that it will also presumptuously delete (ignore) doors 118 * adjacent walls. Note that it will also presumptuously delete (ignore) doors
132 * that it doesn't know how to correctly expand. 119 * that it doesn't know how to correctly expand.
133 */ 120 */
134static void expand_door(char **newlayout, int i, int j, char **layout, 121static void
135 int xsize, int ysize) { 122expand_door (Layout &newlayout, int i, int j, Layout &layout)
123{
136 int wall_pattern = calc_pattern('#', layout, i, j, xsize, ysize); 124 int wall_pattern = calc_pattern ('#', layout, i, j);
137 int door_pattern = calc_pattern('D', layout, i, j, xsize, ysize); 125 int door_pattern = calc_pattern ('D', layout, i, j);
138 int join_pattern; 126 int join_pattern;
139 127
140 /* 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
141 * 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
142 * disconnect from the other door. */ 130 * disconnect from the other door. */
143 if (wall_pattern & 3) { 131 if (wall_pattern & 3)
144 join_pattern = wall_pattern; 132 join_pattern = wall_pattern;
145 } else { 133 else
146 join_pattern = door_pattern; 134 join_pattern = door_pattern;
147 }
148 135
149 newlayout[i*2][j*2] = 'D'; 136 newlayout[i * 2][j * 2] = 'D';
150 if (i+1 < xsize) {
151 if (join_pattern & 1) { /* there is a door/wall to the right */
152 newlayout[i*2+1][j*2]='D';
153 }
154 }
155 137
156 if (j+1 < ysize) { 138 if (i + 1 < layout.w)
157 if (join_pattern & 2) { /* there is a door/wall below */ 139 if (join_pattern & 1)
140 /* there is a door/wall to the right */
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 */
158 newlayout[i*2][j*2+1]='D'; 146 newlayout[i * 2][j * 2 + 1] = 'D';
159 }
160 }
161} 147}
162 148
149void
150expand2x (Layout &layout)
151{
152 Layout new_layout (layout.w * 2 - 1, layout.h * 2 - 1);
153
154 new_layout.clear ();
155
156 for (int i = 0; i < layout.w; i++)
157 for (int j = 0; j < layout.h; j++)
158 switch (layout[i][j])
159 {
160 case '#': expand_wall (new_layout, i, j, layout); break;
161 case 'D': expand_door (new_layout, i, j, layout); break;
162 default: expand_misc (new_layout, i, j, layout); break;
163 }
164
165 layout.swap (new_layout);
166}
167

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines