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

Comparing deliantra/server/random_maps/random_map.C (file contents):
Revision 1.30 by root, Sun Jul 1 05:00:19 2007 UTC vs.
Revision 1.36 by root, Tue Apr 15 18:43:11 2008 UTC

1/* 1/*
2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team 4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * Crossfire TRT is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or 10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * 20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de> 21 * The authors can be reached via e-mail to <support@deliantra.net>
22 */ 22 */
23 23
24#include <time.h> 24#include <time.h>
25#include <stdio.h> 25#include <stdio.h>
26#include <global.h> 26#include <global.h>
27#include <maze_gen.h>
28#include <room_gen.h>
29#include <random_map.h> 27#include <random_map.h>
30#include <rproto.h> 28#include <rproto.h>
31#include <sproto.h> 29#include <sproto.h>
32 30
33#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__); 31#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__);
34 32
33static void symmetrize_layout (Layout maze, random_map_params *RP);
34static void rotate_layout (Layout maze, int rotation);
35
35void 36void
36dump_layout (char **layout, random_map_params *RP) 37dump_layout (Layout layout)
37{ 38{
38 { 39 for (int j = 0; j < layout->h; j++)
39 int i, j;
40
41 for (i = 0; i < RP->Xsize; i++)
42 { 40 {
43 for (j = 0; j < RP->Ysize; j++) 41 for (int i = 0; i < layout->w; i++)
44 { 42 putc (layout[i][j] ? layout[i][j] : ' ', stdout);
45 if (layout[i][j] == 0) 43
46 layout[i][j] = ' '; 44 putc ('\n', stdout);
47 printf ("%c", layout[i][j]);
48 if (layout[i][j] == ' ')
49 layout[i][j] = 0;
50 }
51 printf ("\n");
52 } 45 }
53 } 46
54 printf ("\n"); 47 putc ('\n', stdout);
55} 48}
56 49
57bool 50bool
58maptile::generate_random_map (random_map_params *RP) 51maptile::generate_random_map (random_map_params *RP)
59{ 52{
60 char **layout, buf[16384]; 53 char buf[16384];
61 int i; 54 int i;
62 55
63 RP->Xsize = RP->xsize; 56 RP->Xsize = RP->xsize;
64 RP->Ysize = RP->ysize; 57 RP->Ysize = RP->ysize;
65 58
114 * the numeric layoutstyle, so there is only one area that actually 107 * the numeric layoutstyle, so there is only one area that actually
115 * calls the code to make the maps. 108 * calls the code to make the maps.
116 */ 109 */
117 if (strstr (RP->layoutstyle, "onion")) 110 if (strstr (RP->layoutstyle, "onion"))
118 RP->map_layout_style = LAYOUT_ONION; 111 RP->map_layout_style = LAYOUT_ONION;
119
120 if (strstr (RP->layoutstyle, "maze")) 112 else if (strstr (RP->layoutstyle, "maze"))
121 RP->map_layout_style = LAYOUT_MAZE; 113 RP->map_layout_style = LAYOUT_MAZE;
122
123 if (strstr (RP->layoutstyle, "spiral")) 114 else if (strstr (RP->layoutstyle, "spiral"))
124 RP->map_layout_style = LAYOUT_SPIRAL; 115 RP->map_layout_style = LAYOUT_SPIRAL;
125
126 if (strstr (RP->layoutstyle, "rogue")) 116 else if (strstr (RP->layoutstyle, "rogue"))
127 RP->map_layout_style = LAYOUT_ROGUELIKE; 117 RP->map_layout_style = LAYOUT_ROGUELIKE;
128
129 if (strstr (RP->layoutstyle, "snake")) 118 else if (strstr (RP->layoutstyle, "snake"))
130 RP->map_layout_style = LAYOUT_SNAKE; 119 RP->map_layout_style = LAYOUT_SNAKE;
131
132 if (strstr (RP->layoutstyle, "squarespiral")) 120 else if (strstr (RP->layoutstyle, "squarespiral"))
133 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL; 121 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
134
135 /* No style found - choose one randomly */
136 if (RP->map_layout_style == LAYOUT_NONE) 122 else if (RP->map_layout_style == LAYOUT_NONE)
137 RP->map_layout_style = rndm (NROFLAYOUTS - 1) + 1; 123 RP->map_layout_style = rndm (NROFLAYOUTS - 1) + 1; /* No style found - choose one randomly */
124 else
125 abort ();
138 126
139 layout = layoutgen (RP); 127 Layout layout = layoutgen (RP);
140 128
141#ifdef RMAP_DEBUG 129#ifdef RMAP_DEBUG
142 dump_layout (layout, RP); 130 dump_layout (layout);
143#endif 131#endif
144 132
145 /* increment these for the current map */ 133 /* increment these for the current map */
146 RP->dungeon_level += 1; 134 ++RP->dungeon_level;
147 /* allow constant-difficulty maps. */
148 /* difficulty+=1; */
149 135
150 /* rotate the layout randomly */ 136 // need to patch RP becasue following code doesn't use the Layout object
151 layout = rotate_layout (layout, rndm (4), RP); 137 RP->Xsize = layout->w;
152#ifdef RMAP_DEBUG 138 RP->Ysize = layout->h;
153 dump_layout (layout, RP);
154#endif
155 139
156 /* allocate the map and set the floor */ 140 /* allocate the map and set the floor */
157 make_map_floor (layout, RP->floorstyle, RP); 141 make_map_floor (layout, RP->floorstyle, RP);
158 142
159 /* set region */ 143 /* set region */
211 195
212 CEDE; 196 CEDE;
213 197
214 unblock_exits (this, layout, RP); 198 unblock_exits (this, layout, RP);
215 199
216 /* free the layout */
217 for (i = 0; i < RP->Xsize; i++)
218 free (layout[i]);
219
220 free (layout);
221
222 msg = strdup (buf); 200 msg = strdup (buf);
223 in_memory = MAP_IN_MEMORY; 201 in_memory = MAP_ACTIVE;
224 202
225 CEDE; 203 CEDE;
226 204
227 return 1; 205 return 1;
228} 206}
229 207
230/* function selects the layout function and gives it whatever 208/* function selects the layout function and gives it whatever
231 arguments it needs. */ 209 arguments it needs. */
232char ** 210Layout
233layoutgen (random_map_params *RP) 211layoutgen (random_map_params *RP)
234{ 212{
235 char **maze = 0; 213 Layout layout (RP);
236 int oxsize = RP->Xsize, oysize = RP->Ysize;
237 214
238 switch (RP->map_layout_style) 215 switch (RP->map_layout_style)
239 { 216 {
240 case LAYOUT_ONION: 217 case LAYOUT_ONION:
241 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); 218 map_gen_onion (layout, RP->layoutoptions1, RP->layoutoptions2);
219
242 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) 220 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
243 roomify_layout (maze, RP); 221 roomify_layout (layout, RP);
222
244 break; 223 break;
245 224
246 case LAYOUT_MAZE: 225 case LAYOUT_MAZE:
247 maze = maze_gen (RP->Xsize, RP->Ysize, rndm (2)); 226 maze_gen (layout, rndm (2));
227
248 if (!(rndm (2))) 228 if (!(rndm (2)))
249 doorify_layout (maze, RP); 229 doorify_layout (layout, RP);
230
250 break; 231 break;
251 232
252 case LAYOUT_SPIRAL: 233 case LAYOUT_SPIRAL:
253 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1); 234 map_gen_spiral (layout, RP->layoutoptions1);
235
254 if (!(rndm (2))) 236 if (!(rndm (2)))
255 doorify_layout (maze, RP); 237 doorify_layout (layout, RP);
238
256 break; 239 break;
257 240
258 case LAYOUT_ROGUELIKE: 241 case LAYOUT_ROGUELIKE:
259 /* Don't put symmetry in rogue maps. There isn't much reason to 242 /* Don't put symmetry in rogue maps. There isn't much reason to
260 * do so in the first place (doesn't make it any more interesting), 243 * do so in the first place (doesn't make it any more interesting),
262 * spirals, or maps with lots of passages - making a symmetric rogue 245 * spirals, or maps with lots of passages - making a symmetric rogue
263 * map fails because its likely that the passages the symmetry process 246 * map fails because its likely that the passages the symmetry process
264 * creates may not connect the rooms. 247 * creates may not connect the rooms.
265 */ 248 */
266 RP->symmetry_used = SYMMETRY_NONE; 249 RP->symmetry_used = SYMMETRY_NONE;
267 RP->Ysize = oysize;
268 RP->Xsize = oxsize;
269 maze = roguelike_layout_gen (RP->Xsize, RP->Ysize, RP->layoutoptions1); 250 roguelike_layout_gen (layout, RP->layoutoptions1);
270 /* no doorifying... done already */ 251 /* no doorifying... done already */
271 break; 252 break;
272 253
273 case LAYOUT_SNAKE: 254 case LAYOUT_SNAKE:
274 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 255 make_snake_layout (layout, RP->layoutoptions1);
256
275 if (rndm (2)) 257 if (rndm (2))
276 roomify_layout (maze, RP); 258 roomify_layout (layout, RP);
259
277 break; 260 break;
278 261
279 case LAYOUT_SQUARE_SPIRAL: 262 case LAYOUT_SQUARE_SPIRAL:
280 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 263 make_square_spiral_layout (layout, RP->layoutoptions1);
264
281 if (rndm (2)) 265 if (rndm (2))
282 roomify_layout (maze, RP); 266 roomify_layout (layout, RP);
267
283 break; 268 break;
284 }
285 269
286 maze = symmetrize_layout (maze, RP->symmetry_used, RP); 270 default:
271 abort ();
272 }
273
274 /* rotate the layout randomly */
275 rotate_layout (layout, rndm (4));
276
277 symmetrize_layout (layout, RP);
287 278
288#ifdef RMAP_DEBUG 279#ifdef RMAP_DEBUG
289 dump_layout (maze, RP); 280 dump_layout (layout);
290#endif 281#endif
291 282
292 if (RP->expand2x) 283 if (RP->expand2x)
293 { 284 expand2x (layout);
294 maze = expand2x (maze, RP->Xsize, RP->Ysize);
295 RP->Xsize = RP->Xsize * 2 - 1;
296 RP->Ysize = RP->Ysize * 2 - 1;
297 }
298 285
299 return maze; 286 return layout;
300} 287}
301 288
302/* takes a map and makes it symmetric: adjusts Xsize and 289/* takes a map and makes it symmetric: adjusts Xsize and
303Ysize to produce a symmetric map. */ 290 * Ysize to produce a symmetric map.
304char ** 291 */
292static void
305symmetrize_layout (char **maze, int sym, random_map_params *RP) 293symmetrize_layout (Layout layout, random_map_params *RP)
306{ 294{
307 int i, j;
308 char **sym_maze;
309 int Xsize_orig, Ysize_orig;
310
311 Xsize_orig = RP->Xsize;
312 Ysize_orig = RP->Ysize;
313 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */
314 if (sym == SYMMETRY_NONE) 295 if (RP->symmetry_used == SYMMETRY_NONE)
315 {
316 RP->Xsize = Xsize_orig;
317 RP->Ysize = Ysize_orig;
318 return maze; 296 return;
319 }
320 /* pick new sizes */
321 RP->Xsize = ((sym == SYMMETRY_X || sym == SYMMETRY_XY) ? RP->Xsize * 2 - 3 : RP->Xsize);
322 RP->Ysize = ((sym == SYMMETRY_Y || sym == SYMMETRY_XY) ? RP->Ysize * 2 - 3 : RP->Ysize);
323 297
324 sym_maze = (char **) calloc (sizeof (char *), RP->Xsize); 298 Layout sym_layout (
325 for (i = 0; i < RP->Xsize; i++) 299 RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY ? layout->w * 2 - 3 : layout->w,
326 sym_maze[i] = (char *) calloc (sizeof (char), RP->Ysize); 300 RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY ? layout->h * 2 - 3 : layout->h
301 );
327 302
328 if (sym == SYMMETRY_X) 303 if (RP->symmetry_used == SYMMETRY_X)
329 for (i = 0; i < RP->Xsize / 2 + 1; i++) 304 for (int i = 0; i < sym_layout->w / 2 + 1; i++)
330 for (j = 0; j < RP->Ysize; j++) 305 for (int j = 0; j < sym_layout->h; j++)
331 { 306 {
332 sym_maze[i][j] = maze[i][j]; 307 sym_layout[i ][j] =
333 sym_maze[RP->Xsize - i - 1][j] = maze[i][j]; 308 sym_layout[sym_layout->w - i - 1][j] = layout[i][j];
334 }; 309 }
310
335 if (sym == SYMMETRY_Y) 311 if (RP->symmetry_used == SYMMETRY_Y)
336 for (i = 0; i < RP->Xsize; i++) 312 for (int i = 0; i < sym_layout->w; i++)
337 for (j = 0; j < RP->Ysize / 2 + 1; j++) 313 for (int j = 0; j < sym_layout->h / 2 + 1; j++)
338 {
339 sym_maze[i][j] = maze[i][j];
340 sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
341 } 314 {
342 if (sym == SYMMETRY_XY) 315 sym_layout[i][j ] =
343 for (i = 0; i < RP->Xsize / 2 + 1; i++) 316 sym_layout[i][sym_layout->h - j - 1] = layout[i][j];
344 for (j = 0; j < RP->Ysize / 2 + 1; j++)
345 { 317 }
346 sym_maze[i][j] = maze[i][j]; 318
347 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 319 if (RP->symmetry_used == SYMMETRY_XY)
348 sym_maze[RP->Xsize - i - 1][j] = maze[i][j]; 320 for (int i = 0; i < sym_layout->w / 2 + 1; i++)
349 sym_maze[RP->Xsize - i - 1][RP->Ysize - j - 1] = maze[i][j]; 321 for (int j = 0; j < sym_layout->h / 2 + 1; j++)
350 } 322 {
351 /* delete the old maze */ 323 sym_layout[i ][j ] =
352 for (i = 0; i < Xsize_orig; i++) 324 sym_layout[i ][sym_layout->h - j - 1] =
353 free (maze[i]); 325 sym_layout[sym_layout->w - i - 1][j ] =
354 free (maze); 326 sym_layout[sym_layout->w - i - 1][sym_layout->h - j - 1] = layout[i][j];
327 }
328
329 layout.swap (sym_layout);
330 sym_layout.free ();
331
355 /* reconnect disjointed spirals */ 332 /* reconnect disjointed spirals */
356 if (RP->map_layout_style == LAYOUT_SPIRAL)
357 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
358 /* reconnect disjointed nethackmazes: the routine for 333 /* reconnect disjointed nethacklayouts: the routine for
359 spirals will do the trick? */ 334 spirals will do the trick? */
335 if (RP->map_layout_style == LAYOUT_SPIRAL
360 if (RP->map_layout_style == LAYOUT_ROGUELIKE) 336 || RP->map_layout_style == LAYOUT_ROGUELIKE)
361 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 337 connect_spirals (layout->w, layout->h, RP->symmetry_used, layout);
362
363 return sym_maze;
364} 338}
365
366 339
367/* takes a map and rotates it. This completes the 340/* takes a map and rotates it. This completes the
368 onion layouts, making them possibly centered on any wall. 341 onion layouts, making them possibly centered on any wall.
369 It'll modify Xsize and Ysize if they're swapped. 342 It'll modify Xsize and Ysize if they're swapped.
370*/ 343*/
371 344static void
372char ** 345rotate_layout (Layout layout, int rotation)
373rotate_layout (char **maze, int rotation, random_map_params *RP)
374{ 346{
375 char **new_maze; 347 int w = layout->w;
376 int i, j; 348 int h = layout->h;
377 349
378 switch (rotation) 350 switch (rotation)
379 { 351 {
380 case 0: 352 case 2: /* a reflection */
381 return maze; 353 {
354 Layout new_layout (w, h);
355
356 for (int i = 0; i < w; i++) /* copy a reflection back */
357 for (int j = 0; j < h; j++)
358 new_layout[i][j] = layout[w - i - 1][h - j - 1];
359
360 layout.swap (new_layout);
361 new_layout.free ();
362 }
382 break; 363 break;
383 case 2: /* a reflection */
384 {
385 char *newmaze = (char *) malloc (sizeof (char) * RP->Xsize * RP->Ysize);
386 364
387 for (i = 0; i < RP->Xsize; i++)
388 { /* make a copy */
389 for (j = 0; j < RP->Ysize; j++)
390 {
391 newmaze[i * RP->Ysize + j] = maze[i][j];
392 }
393 }
394 for (i = 0; i < RP->Xsize; i++)
395 { /* copy a reflection back */
396 for (j = 0; j < RP->Ysize; j++)
397 {
398 maze[i][j] = newmaze[(RP->Xsize - i - 1) * RP->Ysize + RP->Ysize - j - 1];
399 }
400 }
401 free (newmaze);
402 return maze;
403 break;
404 }
405 case 1: 365 case 1:
406 case 3: 366 case 3:
407 { 367 {
408 int swap; 368 Layout new_layout (h, w);
409 new_maze = (char **) calloc (sizeof (char *), RP->Ysize); 369
410 for (i = 0; i < RP->Ysize; i++)
411 {
412 new_maze[i] = (char *) calloc (sizeof (char), RP->Xsize);
413 }
414 if (rotation == 1) /* swap x and y */ 370 if (rotation == 1) /* swap x and y */
415 for (i = 0; i < RP->Xsize; i++) 371 for (int i = 0; i < w; i++)
416 for (j = 0; j < RP->Ysize; j++) 372 for (int j = 0; j < h; j++)
417 new_maze[j][i] = maze[i][j]; 373 new_layout[j][i] = layout[i][j];
418 374
419 if (rotation == 3) 375 if (rotation == 3) /* swap x and y */
420 { /* swap x and y */
421 for (i = 0; i < RP->Xsize; i++) 376 for (int i = 0; i < w; i++)
422 for (j = 0; j < RP->Ysize; j++) 377 for (int j = 0; j < h; j++)
423 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1]; 378 new_layout[j][i] = layout[w - i - 1][h - j - 1];
379
380 layout.swap (new_layout);
381 new_layout.free ();
424 } 382 }
425
426 /* delete the old layout */
427 for (i = 0; i < RP->Xsize; i++)
428 free (maze[i]);
429 free (maze);
430
431 swap = RP->Ysize;
432 RP->Ysize = RP->Xsize;
433 RP->Xsize = swap;
434 return new_maze;
435 break; 383 break;
436 }
437 } 384 }
438 return NULL;
439} 385}
440 386
441/* take a layout and make some rooms in it. 387/* take a layout and make some rooms in it.
442 --works best on onions.*/ 388 --works best on onions.*/
443void 389void
595/* puts doors at appropriate locations in a layout. */ 541/* puts doors at appropriate locations in a layout. */
596void 542void
597doorify_layout (char **maze, random_map_params *RP) 543doorify_layout (char **maze, random_map_params *RP)
598{ 544{
599 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */ 545 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */
600 char *doorlist_x;
601 char *doorlist_y;
602 int doorlocs = 0; /* # of available doorlocations */ 546 int doorlocs = 0; /* # of available doorlocations */
603 int i, j; 547 int i, j;
604 548
605 doorlist_x = (char *) malloc (sizeof (int) * RP->Xsize * RP->Ysize); 549 char *doorlist_x = salloc<char> (RP->Xsize * RP->Ysize);
606 doorlist_y = (char *) malloc (sizeof (int) * RP->Xsize * RP->Ysize); 550 char *doorlist_y = salloc<char> (RP->Xsize * RP->Ysize);
607
608 551
609 /* make a list of possible door locations */ 552 /* make a list of possible door locations */
610 for (i = 1; i < RP->Xsize - 1; i++) 553 for (i = 1; i < RP->Xsize - 1; i++)
611 for (j = 1; j < RP->Ysize - 1; j++) 554 for (j = 1; j < RP->Ysize - 1; j++)
612 { 555 {
640 doorlocs--; 583 doorlocs--;
641 doorlist_x[di] = doorlist_x[doorlocs]; 584 doorlist_x[di] = doorlist_x[doorlocs];
642 doorlist_y[di] = doorlist_y[doorlocs]; 585 doorlist_y[di] = doorlist_y[doorlocs];
643 } 586 }
644 587
645 free (doorlist_x); 588 sfree (doorlist_x, RP->Xsize * RP->Ysize);
646 free (doorlist_y); 589 sfree (doorlist_y, RP->Xsize * RP->Ysize);
647} 590}
648 591
649void 592void
650write_map_parameters_to_string (char *buf, random_map_params *RP) 593write_map_parameters_to_string (char *buf, random_map_params *RP)
651{ 594{
1013 956
1014 walk->copy_to (tmp); 957 walk->copy_to (tmp);
1015 insert_ob_in_ob (tmp, dest_ob); 958 insert_ob_in_ob (tmp, dest_ob);
1016 } 959 }
1017} 960}
961
962/////////////////////////////////////////////////////////////////////////////
963
964LayoutData::LayoutData (int w, int h)
965: w(w), h(h)
966{
967 int size = (sizeof (char *) + sizeof (char) * h) * w;
968
969 col = (char **)salloc<char> (size);
970
971 char *data = (char *)(col + w);
972
973 for (int x = w; x--; )
974 col [x] = data + x * h;
975}
976
977LayoutData::~LayoutData ()
978{
979 int size = (sizeof (char *) + sizeof (char) * h) * w;
980
981 sfree ((char *)col, size);
982}
983
984void LayoutData::clear (char fill)
985{
986 memset (col [0], fill, w * h);
987}
988
989void LayoutData::border (char fill)
990{
991 for (int i = 0; i < w; i++) col [i][0] = col [i][h - 1] = fill;
992 for (int j = 0; j < h; j++) col [0][j] = col [w - 1][j] = fill;
993}
994

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines