ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/expand2x.c
Revision: 1.2
Committed: Sun Aug 13 17:16:03 2006 UTC (17 years, 9 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +1 -1 lines
State: FILE REMOVED
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# User Rev Content
1 root 1.1 /*
2     * Expands a layout by 2x in each dimension.
3     * H. S. Teoh
4     * --------------------------------------------------------------------------
5 elmex 1.2 * $Id$
6 root 1.1 *
7     * ALGORITHM
8     *
9     * ... (TBW)
10     */
11    
12     #include <stdlib.h> /* just in case */
13     #include <expand2x.h> /* use compiler to do sanity check */
14    
15    
16     /* PROTOTYPES */
17    
18     static void expand_misc(char **newlayout, int i, int j, char **layout,
19     int xsize, int ysize);
20     static void expand_wall(char **newlayout, int i, int j, char **layout,
21     int xsize, int ysize);
22     static void expand_door(char **newlayout, int i, int j, char **layout,
23     int xsize, int ysize);
24    
25    
26     /* FUNCTIONS */
27    
28     char **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    
63     /* 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:
65     * X ---> X \0
66     * \0 \0
67     */
68     static void expand_misc(char **newlayout, int i, int j, char **layout,
69     int xsize, int ysize) {
70     newlayout[i*2][j*2] = layout[i][j];
71     /* (Note: no need to reset rest of 2x2 area to \0 because calloc does that
72     * for us.) */
73     }
74    
75     /* Returns a bitmap that represents which squares on the right and bottom
76     * edges of a square (i,j) match the given character:
77     * 1 match on (i+1, j)
78     * 2 match on (i, j+1)
79     * 4 match on (i+1, j+1)
80     * and the possible combinations thereof.
81     */
82     static int calc_pattern(char ch, char **layout, int i, int j,
83     int xsize, int ysize) {
84     int pattern = 0;
85    
86     if (i+1<xsize && layout[i+1][j]==ch)
87     pattern |= 1;
88    
89     if (j+1<ysize) {
90     if (layout[i][j+1]==ch)
91     pattern |= 2;
92     if (i+1<xsize && layout[i+1][j+1]==ch)
93     pattern |= 4;
94     }
95    
96     return pattern;
97     }
98    
99     /* 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
101     * walls.
102     */
103     static void expand_wall(char **newlayout, int i, int j, char **layout,
104     int xsize, int ysize) {
105     int wall_pattern = calc_pattern('#', layout, i, j, xsize, ysize);
106     int door_pattern = calc_pattern('D', layout, i, j, xsize, ysize);
107     int both_pattern = wall_pattern | door_pattern;
108    
109     newlayout[i*2][j*2] = '#';
110     if (i+1 < xsize) {
111     if (both_pattern & 1) { /* join walls/doors to the right */
112     /* newlayout[i*2+1][j*2] = '#'; */
113     newlayout[i*2+1][j*2] = layout[i+1][j];
114     }
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     }
122    
123     if (wall_pattern==7) { /* if orig layout is a 2x2 wall block,
124     * we fill the result with walls. */
125     newlayout[i*2+1][j*2+1] = '#';
126     }
127     }
128     }
129    
130     /* 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
132     * that it doesn't know how to correctly expand.
133     */
134     static void expand_door(char **newlayout, int i, int j, char **layout,
135     int xsize, int ysize) {
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    
149     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    
156     if (j+1 < ysize) {
157     if (join_pattern & 2) { /* there is a door/wall below */
158     newlayout[i*2][j*2+1]='D';
159     }
160     }
161     }
162