Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 * -------------------------------------------------------------------------- 00003 * $Id: expand2x.c 11578 2009-02-23 22:02:27Z lalo $ 00004 * 00005 * ALGORITHM 00006 * 00007 * ... (TBW) 00008 */ 00009 00017 #include <stdlib.h> /* just in case */ 00018 #include <expand2x.h> /* use compiler to do sanity check */ 00019 00020 00021 /* PROTOTYPES */ 00022 00023 static void expand_misc(char **newlayout, int i, int j, char **layout); 00024 static void expand_wall(char **newlayout, int i, int j, char **layout, int xsize, int ysize); 00025 static void expand_door(char **newlayout, int i, int j, char **layout, int xsize, int ysize); 00026 00027 /* FUNCTIONS */ 00028 00039 char **expand2x(char **layout, int xsize, int ysize) { 00040 int i, j; 00041 int nxsize = xsize*2-1; 00042 int nysize = ysize*2-1; 00043 00044 /* Allocate new layout */ 00045 char **newlayout = (char **)calloc(sizeof(char *), nxsize); 00046 for (i = 0; i < nxsize; i++) { 00047 newlayout[i] = (char *)calloc(sizeof(char), nysize); 00048 } 00049 00050 for (i = 0; i < xsize; i++) { 00051 for (j = 0; j < ysize; j++) { 00052 switch (layout[i][j]) { 00053 case '#': 00054 expand_wall(newlayout, i, j, layout, xsize, ysize); 00055 break; 00056 00057 case 'D': 00058 expand_door(newlayout, i, j, layout, xsize, ysize); 00059 break; 00060 00061 default: 00062 expand_misc(newlayout, i, j, layout); 00063 } 00064 } 00065 } 00066 00067 /* Dump old layout */ 00068 for (i = 0; i < xsize; i++) { 00069 free(layout[i]); 00070 } 00071 free(layout); 00072 00073 return newlayout; 00074 } 00075 00089 static void expand_misc(char **newlayout, int i, int j, char **layout) { 00090 newlayout[i*2][j*2] = layout[i][j]; 00091 /* (Note: no need to reset rest of 2x2 area to \0 because calloc does that 00092 * for us.) */ 00093 } 00094 00115 static int calc_pattern(char ch, char **layout, int i, int j, int xsize, int ysize) { 00116 int pattern = 0; 00117 00118 if (i+1 < xsize && layout[i+1][j] == ch) 00119 pattern |= 1; 00120 00121 if (j+1 < ysize) { 00122 if (layout[i][j+1] == ch) 00123 pattern |= 2; 00124 if (i+1 < xsize && layout[i+1][j+1] == ch) 00125 pattern |= 4; 00126 } 00127 00128 return pattern; 00129 } 00130 00146 static void expand_wall(char **newlayout, int i, int j, char **layout, int xsize, int ysize) { 00147 int wall_pattern = calc_pattern('#', layout, i, j, xsize, ysize); 00148 int door_pattern = calc_pattern('D', layout, i, j, xsize, ysize); 00149 int both_pattern = wall_pattern|door_pattern; 00150 00151 newlayout[i*2][j*2] = '#'; 00152 if (i+1 < xsize) { 00153 if (both_pattern&1) { 00154 /* join walls/doors to the right */ 00155 newlayout[i*2+1][j*2] = layout[i+1][j]; 00156 } 00157 } 00158 00159 if (j+1 < ysize) { 00160 if (both_pattern&2) { 00161 /* join walls/doors to the bottom */ 00162 newlayout[i*2][j*2+1] = layout[i][j+1]; 00163 } 00164 00165 if (wall_pattern == 7) { 00166 /* if orig layout is a 2x2 wall block, 00167 * we fill the result with walls. */ 00168 newlayout[i*2+1][j*2+1] = '#'; 00169 } 00170 } 00171 } 00172 00188 static void expand_door(char **newlayout, int i, int j, char **layout, int xsize, int ysize) { 00189 int wall_pattern = calc_pattern('#', layout, i, j, xsize, ysize); 00190 int door_pattern = calc_pattern('D', layout, i, j, xsize, ysize); 00191 int join_pattern; 00192 00193 /* Doors "like" to connect to walls more than other doors. If there is 00194 * a wall and another door, this door will connect to the wall and 00195 * disconnect from the other door. */ 00196 if (wall_pattern&3) { 00197 join_pattern = wall_pattern; 00198 } else { 00199 join_pattern = door_pattern; 00200 } 00201 00202 newlayout[i*2][j*2] = 'D'; 00203 if (i+1 < xsize) { 00204 if (join_pattern&1) { 00205 /* there is a door/wall to the right */ 00206 newlayout[i*2+1][j*2] = 'D'; 00207 } 00208 } 00209 00210 if (j+1 < ysize) { 00211 if (join_pattern&2) { 00212 /* there is a door/wall below */ 00213 newlayout[i*2][j*2+1] = 'D'; 00214 } 00215 } 00216 }