1 #include "global.h"
2
3 #ifdef EYE_CANDY
4 #include "eye_candy_window.h"
5 #endif
6 #ifdef CLUSTER_INSIDES
7 #include "../cluster.h"
8 #endif
9 #include "../asc.h"
10
11 #define LATEST_MAP_VERSION 1
12
destroy_map()13 void destroy_map()
14 {
15 int i;
16
17 //kill the tile and height map
18 if (tile_map)
19 {
20 free (tile_map);
21 tile_map = NULL;
22 }
23
24 if (height_map)
25 {
26 free (height_map);
27 height_map = NULL;
28 }
29
30
31 //kill the 3d objects links
32 for (i = 0; i < MAX_OBJ_3D; i++)
33 {
34 if (objects_list[i])
35 {
36 free (objects_list[i]);
37 objects_list[i] = NULL; // kill any reference to it
38 }
39 }
40
41 //kill the 2d objects links
42 for (i = 0; i < MAX_OBJ_2D; i++)
43 {
44 if (obj_2d_list[i])
45 {
46 free (obj_2d_list[i]);
47 obj_2d_list[i] = NULL; // kill any reference to it
48 }
49 }
50
51 //kill the lights links
52 for (i = 0; i < MAX_LIGHTS; i++)
53 {
54 if (lights_list[i])
55 {
56 free (lights_list[i]);
57 lights_list[i] = NULL; // kill any reference to it
58 }
59 }
60
61 destroy_all_particles();
62 #ifdef EYE_CANDY
63 destroy_all_eye_candy();
64 #endif
65
66 selected_3d_object=selected_2d_object=selected_light=selected_particles_object=-1;
67 }
68
save_map(const char * file_name)69 int save_map (const char* file_name)
70 {
71 static const char* badobject_file_name = "./3dobjects/badobject.e3d"; // Stored for deleted 3D objects
72
73 int i,j;
74 map_header cur_map_header;
75 char * mem_map_header=(char *)&cur_map_header;
76
77 object3d_io cur_3d_obj_io;
78 int obj_3d_no=0;
79 int obj_3d_io_size;
80
81 obj_2d_io cur_2d_obj_io;
82 int obj_2d_no=0;
83 int obj_2d_io_size;
84
85 light_io cur_light_io;
86 int lights_no=0;
87 int lights_io_size;
88
89 particles_io cur_particles_io;
90 int particles_no=0;
91 int particles_io_size;
92
93 #ifdef ZLIBW
94 gzFile f = NULL;
95 #else //ZLIBW
96 FILE *f = NULL;
97 #endif //ZLIBW
98
99 #ifdef CLUSTER_INSIDES
100 char* occupied = NULL;
101 char* cluster_data = NULL;
102 int cluster_data_len = 0;
103 #endif
104
105 //get the sizes of structures (they might change in the future)
106 obj_3d_io_size=sizeof(object3d_io);
107 obj_2d_io_size=sizeof(obj_2d_io);
108 lights_io_size=sizeof(light_io);
109 particles_io_size=sizeof(particles_io);
110
111 //get the number of objects and lights
112 for (i = 0; i < MAX_OBJ_3D; i++)
113 if (objects_list[i]) obj_3d_no++;
114 for (i = 0; i < MAX_OBJ_2D; i++)
115 if (obj_2d_list[i]) obj_2d_no++;
116 for (i = 0; i < MAX_LIGHTS; i++)
117 if (lights_list[i] && !lights_list[i]->locked) lights_no++;
118 // We ignore temporary particle systems (i.e. ones with a ttl)
119 for (i = 0; i < MAX_PARTICLE_SYSTEMS; i++)
120 if (particles_list[i] && particles_list[i]->def && particles_list[i]->def != &def) particles_no++;
121
122 //ok, now build the header...
123 //clear the header
124 memset (mem_map_header, 0, sizeof (map_header));
125
126 //build the file signature
127 cur_map_header.file_sig[0]='e';
128 cur_map_header.file_sig[1]='l';
129 cur_map_header.file_sig[2]='m';
130 cur_map_header.file_sig[3]='f';
131
132 cur_map_header.tile_map_x_len=tile_map_size_x;
133 cur_map_header.tile_map_y_len=tile_map_size_y;
134 cur_map_header.tile_map_offset=sizeof(map_header);
135 cur_map_header.height_map_offset=cur_map_header.tile_map_offset+tile_map_size_x*tile_map_size_y;
136 cur_map_header.obj_3d_struct_len=obj_3d_io_size;
137 cur_map_header.obj_3d_no=obj_3d_no;
138 cur_map_header.obj_3d_offset=cur_map_header.height_map_offset+tile_map_size_x*tile_map_size_y*6*6;
139 cur_map_header.obj_2d_struct_len=obj_2d_io_size;
140 cur_map_header.obj_2d_no=obj_2d_no;
141 cur_map_header.obj_2d_offset=cur_map_header.obj_3d_offset+obj_3d_no*obj_3d_io_size;
142 cur_map_header.lights_struct_len=lights_io_size;
143 cur_map_header.lights_no=lights_no;
144 cur_map_header.lights_offset=cur_map_header.obj_2d_offset+obj_2d_no*obj_2d_io_size;
145 cur_map_header.dungeon=dungeon;
146 #if defined CLUSTER_INSIDES || defined NEW_LIGHT_FORMAT
147 cur_map_header.version = LATEST_MAP_VERSION;
148 #endif
149 cur_map_header.ambient_r=ambient_r;
150 cur_map_header.ambient_g=ambient_g;
151 cur_map_header.ambient_b=ambient_b;
152 cur_map_header.particles_struct_len=particles_io_size;
153 #ifdef EYE_CANDY
154 eye_candy_done_adding_effect();
155 cur_map_header.particles_no=particles_no + get_eye_candy_count();
156 #else
157 cur_map_header.particles_no=particles_no;
158 #endif
159 cur_map_header.particles_offset=cur_map_header.lights_offset+lights_no*lights_io_size;
160 #ifdef CLUSTER_INSIDES
161 cur_map_header.clusters_offset = cur_map_header.particles_offset + cur_map_header.particles_no * particles_io_size;
162 #endif
163
164 // ok, now let's open/create the file, and start writing the header...
165 #ifdef ZLIBW
166 {
167 char gzfile_name[1024];
168 strcpy(gzfile_name, file_name);
169 //strcat(gzfile_name, ".gz");
170 f= gzopen(gzfile_name, "wb");
171 }
172 #else //ZLIBW
173 f= fopen(file_name, "wb");
174 #endif //ZLIBW
175
176 if (!f) {
177 char msg[500];
178 snprintf (msg, sizeof(msg), "Could not open file for writing: %s", file_name);
179 LOG_ERROR(msg);
180 } else {
181
182 #ifdef ZLIBW
183 //write the header
184 gzwrite(f, mem_map_header, sizeof(map_header));
185
186 //write the tiles map
187 gzwrite(f, tile_map, tile_map_size_x*tile_map_size_y);
188
189 //write the heights map
190 gzwrite(f, height_map, tile_map_size_x*tile_map_size_y*6*6);
191 #else //ZLIBW
192 //write the header
193 fwrite(mem_map_header, sizeof(map_header), 1, f);
194
195 //write the tiles map
196 fwrite(tile_map, tile_map_size_x*tile_map_size_y, 1, f);
197
198 //write the heights map
199 fwrite(height_map, tile_map_size_x*tile_map_size_y*6*6, 1, f);
200 #endif //ZLIBW
201
202 #ifdef CLUSTER_INSIDES
203 // Allocate memory for the occupation map, and initialize
204 // it with the tiles and height maps
205 occupied = calloc (tile_map_size_x*tile_map_size_y*6*6, 1);
206 update_occupied_with_tile_map (occupied, tile_map);
207 update_occupied_with_height_map (occupied, height_map);
208 #endif
209
210 //write the 3d objects
211 j=0;
212 for (i = 0; i < MAX_OBJ_3D; i++)
213 {
214 if (j > obj_3d_no)
215 break;
216
217 if (objects_list[i])
218 {
219 char* cur_3do_pointer = (char *) &cur_3d_obj_io;
220
221 // clear the object
222 memset (cur_3do_pointer, 0, sizeof (object3d_io));
223
224 // For deleted objects, store the "bad object" file name, to make doubly sure the object
225 // is never used (e.g. for harvesting purposes).
226 safe_strncpy(cur_3d_obj_io.file_name,
227 objects_list[i]->blended == 20 ? badobject_file_name : objects_list[i]->file_name,
228 sizeof(cur_3d_obj_io.file_name));
229 cur_3d_obj_io.x_pos = objects_list[i]->x_pos;
230 cur_3d_obj_io.y_pos = objects_list[i]->y_pos;
231 cur_3d_obj_io.z_pos = objects_list[i]->z_pos;
232
233 cur_3d_obj_io.x_rot = objects_list[i]->x_rot;
234 cur_3d_obj_io.y_rot = objects_list[i]->y_rot;
235 cur_3d_obj_io.z_rot = objects_list[i]->z_rot;
236
237 cur_3d_obj_io.self_lit = objects_list[i]->self_lit;
238 cur_3d_obj_io.blended = objects_list[i]->blended;
239
240 cur_3d_obj_io.r = objects_list[i]->color[0];
241 cur_3d_obj_io.g = objects_list[i]->color[1];
242 cur_3d_obj_io.b = objects_list[i]->color[2];
243
244 #ifdef ZLIBW
245 gzwrite (f, cur_3do_pointer, sizeof(object3d_io));
246 #else //ZLIBW
247 fwrite (cur_3do_pointer, sizeof(object3d_io), 1, f);
248 #endif //ZLIBW
249
250 #ifdef CLUSTER_INSIDES
251 if (cur_3d_obj_io.blended != 20)
252 update_occupied_with_3d (occupied, i);
253 #endif
254
255 j++;
256 }
257 }
258
259 //write the 2d objects
260 j = 0;
261 for (i = 0; i < MAX_OBJ_2D; i++)
262 {
263 if (j > obj_2d_no) break;
264 if (obj_2d_list[i])
265 {
266 char* cur_2do_pointer = (char *) &cur_2d_obj_io;
267
268 // clear the object
269 memset (cur_2do_pointer, 0, sizeof (obj_2d_io));
270
271 snprintf (cur_2d_obj_io.file_name, sizeof (cur_2d_obj_io.file_name), "%s", obj_2d_list[i]->file_name);
272 cur_2d_obj_io.x_pos = obj_2d_list[i]->x_pos;
273 cur_2d_obj_io.y_pos = obj_2d_list[i]->y_pos;
274 cur_2d_obj_io.z_pos = obj_2d_list[i]->z_pos;
275
276 cur_2d_obj_io.x_rot = obj_2d_list[i]->x_rot;
277 cur_2d_obj_io.y_rot = obj_2d_list[i]->y_rot;
278 cur_2d_obj_io.z_rot = obj_2d_list[i]->z_rot;
279
280 #ifdef ZLIBW
281 gzwrite (f, cur_2do_pointer, sizeof (obj_2d_io));
282 #else //ZLIBW
283 fwrite (cur_2do_pointer, sizeof (obj_2d_io), 1, f);
284 #endif //ZLIBW
285
286 #ifdef CLUSTER_INSIDES
287 update_occupied_with_2d (occupied, i);
288 #endif
289
290 j++;
291 }
292 }
293
294 //write the lights
295 j=0;
296 for (i = 0; i < MAX_LIGHTS; i++)
297 {
298 if (j > lights_no) break;
299 if (lights_list[i] && !lights_list[i]->locked)
300 {
301 char* cur_light_pointer = (char *) &cur_light_io;
302
303 // clear the object
304 memset (cur_light_pointer, 0, sizeof (light_io));
305
306 cur_light_io.pos_x = lights_list[i]->pos_x;
307 cur_light_io.pos_y = lights_list[i]->pos_y;
308 cur_light_io.pos_z = lights_list[i]->pos_z;
309
310 cur_light_io.r = lights_list[i]->r;
311 cur_light_io.g = lights_list[i]->g;
312 cur_light_io.b = lights_list[i]->b;
313
314 #ifdef NEW_LIGHT_FORMAT
315 // Insert default values for now
316 cur_light_io.spec_r = 255;
317 cur_light_io.spec_g = 255;
318 cur_light_io.spec_b = 255;
319
320 cur_light_io.light_dir_z_sign = 0;
321
322 cur_light_io.quadric_attenuation = 0;
323 cur_light_io.range = 0;
324 cur_light_io.cutoff = -32768;
325 cur_light_io.exponent = 0;
326
327 cur_light_io.light_dir_x = 0;
328 cur_light_io.light_dir_y = 0;
329 #endif
330
331 #ifdef ZLIBW
332 gzwrite (f, cur_light_pointer, sizeof (light_io));
333 #else //ZLIBW
334 fwrite (cur_light_pointer, sizeof (light_io), 1, f);
335 #endif //ZLIBW
336
337 j++;
338 }
339 }
340
341 // Write the particle systems
342 j = 0;
343 for (i = 0; i < MAX_PARTICLE_SYSTEMS; i++)
344 {
345 if (j > particles_no) break;
346 if (particles_list[i] && particles_list[i]->def && particles_list[i]->def != &def)
347 {
348 char *cur_particles_pointer = (char *) &cur_particles_io;
349
350 memset (cur_particles_pointer, 0, sizeof (particles_io));
351
352 snprintf (cur_particles_io.file_name, sizeof (cur_particles_io.file_name), "%s", particles_list[i]->def->file_name);
353 cur_particles_io.x_pos = particles_list[i]->x_pos;
354 cur_particles_io.y_pos = particles_list[i]->y_pos;
355 cur_particles_io.z_pos = particles_list[i]->z_pos;
356 #ifdef ZLIBW
357 gzwrite (f, cur_particles_pointer, sizeof (particles_io));
358 #else //ZLIBW
359 fwrite (cur_particles_pointer, sizeof (particles_io), 1, f);
360 #endif //ZLIBW
361 j++;
362 }
363 }
364
365 #ifdef EYE_CANDY
366 // Write the eye candy effects
367 for (i = 0; i < get_eye_candy_count (); i++)
368 {
369 char *cur_particles_pointer = (char *) &cur_particles_io;
370 serialize_eye_candy_effect (i, &cur_particles_io);
371
372 #ifdef ZLIBW
373 gzwrite (f, cur_particles_pointer, sizeof (particles_io));
374 #else //ZLIBW
375 fwrite (cur_particles_pointer, sizeof (particles_io), 1, f);
376 #endif //ZLIBW
377 }
378 #endif
379
380 #ifdef CLUSTER_INSIDES
381 // Compute the clusters and save them
382 compute_clusters (occupied);
383 free (occupied);
384
385 get_clusters (&cluster_data, &cluster_data_len);
386 #ifdef ZLIBW
387 gzwrite (f, cluster_data, cluster_data_len);
388 #else
389 fwrite (cluster_data, cluster_data_len, 1, f);
390 #endif // ZLIBW
391 free (cluster_data);
392 #endif // CLUSTER_INSIDES
393
394 #ifdef ZLIBW
395 gzclose(f);
396 #else //ZLIBW
397 fclose(f);
398 #endif //ZLIBW
399 }
400
401 return 1;
402
403 }
404
load_map(const char * file_name)405 int load_map (const char* file_name)
406 {
407 int i;
408 map_header cur_map_header;
409 char* mem_map_header=(char *)&cur_map_header;
410 #if defined CLUSTER_INSIDES || defined NEW_LIGHT_FORMAT
411 unsigned char version;
412 #endif
413
414 object3d_io cur_3d_obj_io;
415 int obj_3d_no=0;
416 int obj_3d_io_size;
417
418 obj_2d_io cur_2d_obj_io;
419 int obj_2d_no=0;
420 int obj_2d_io_size;
421
422 light_io cur_light_io;
423 int lights_no=0;
424 int lights_io_size;
425
426 particles_io cur_particles_io;
427 int particles_no=0;
428 int particles_io_size;
429
430 #ifdef ZLIB
431 gzFile f = NULL;
432 f= my_gzopen(file_name, "rb");
433 #else //ZLIB
434 FILE *f = NULL;
435 f= fopen(file_name, "rb");
436 #endif //ZLIB
437 if(!f)return 0;
438
439 #ifdef ZLIB
440 gzread(f, mem_map_header, sizeof(cur_map_header));//header only
441 #else //ZLIB
442 fread(mem_map_header, 1, sizeof(cur_map_header), f);//header only
443 #endif //ZLIB
444
445 //verify if we have a valid file
446 if(cur_map_header.file_sig[0]!='e'
447 || cur_map_header.file_sig[1]!='l'
448 || cur_map_header.file_sig[2]!='m'
449 || cur_map_header.file_sig[3]!='f')
450 {
451 #ifdef ZLIB
452 gzclose(f);
453 #else
454 fclose(f);
455 #endif
456 return 0;
457 }
458
459 destroy_map();//Only destroy the map now....
460
461 //get the map size
462 tile_map_size_x=cur_map_header.tile_map_x_len;
463 tile_map_size_y=cur_map_header.tile_map_y_len;
464
465 //allocate memory for the tile map (it was destroyed)
466 tile_map=(unsigned char *)calloc(tile_map_size_x*tile_map_size_y, 1);
467 //allocates the memory for the heights now
468 height_map=(unsigned char *)calloc(tile_map_size_x*tile_map_size_y*6*6, 1);
469
470 //get the sizes of structures (they might change in the future)
471 obj_3d_io_size=cur_map_header.obj_3d_struct_len;
472 obj_2d_io_size=cur_map_header.obj_2d_struct_len;
473 lights_io_size=cur_map_header.lights_struct_len;
474 particles_io_size=cur_map_header.particles_struct_len;
475
476 //get the number of objects and lights
477 obj_3d_no=cur_map_header.obj_3d_no;
478 obj_2d_no=cur_map_header.obj_2d_no;
479 lights_no=cur_map_header.lights_no;
480 particles_no=cur_map_header.particles_no;
481
482 //get the type of map, and the ambient light
483 dungeon=cur_map_header.dungeon;
484 #if defined CLUSTER_INSIDES || defined NEW_LIGHT_FORMAT
485 version = cur_map_header.version;
486 #endif
487 ambient_r=cur_map_header.ambient_r;
488 ambient_g=cur_map_header.ambient_g;
489 ambient_b=cur_map_header.ambient_b;
490
491 //this is useful if we go in/out a dungeon
492 new_minute();
493
494 //read the tiles map
495 #ifdef ZLIB
496 gzread(f, tile_map, tile_map_size_x*tile_map_size_y);
497 #else //ZLIB
498 fread(tile_map, 1, tile_map_size_x*tile_map_size_y, f);
499 #endif //ZLIB
500
501 //load the tiles in this map, if not already loaded
502 load_map_tiles();
503
504 //read the heights map
505 #ifdef ZLIB
506 gzread(f, height_map, tile_map_size_x*tile_map_size_y*6*6);
507 #else //ZLIB
508 fread(height_map, 1, tile_map_size_x*tile_map_size_y*6*6, f);
509 #endif //ZLIB
510
511 //read the 3d objects
512 for(i=0; i < obj_3d_no; i++)
513 {
514 char *cur_3do_pointer = (char *)&cur_3d_obj_io;
515
516 #ifdef ZLIB
517 gzread (f, cur_3do_pointer, obj_3d_io_size);
518 #else //ZLIB
519 fread (cur_3do_pointer, 1, obj_3d_io_size, f);
520 #endif //ZLIB
521
522 add_e3d_keep_deleted (cur_3d_obj_io.file_name, cur_3d_obj_io.x_pos, cur_3d_obj_io.y_pos, cur_3d_obj_io.z_pos, cur_3d_obj_io.x_rot, cur_3d_obj_io.y_rot, cur_3d_obj_io.z_rot, cur_3d_obj_io.self_lit, cur_3d_obj_io.blended, cur_3d_obj_io.r, cur_3d_obj_io.g, cur_3d_obj_io.b);
523 }
524
525 //read the 2d objects
526 for(i=0;i<obj_2d_no;i++)
527 {
528 char * cur_2do_pointer=(char *)&cur_2d_obj_io;
529 #ifdef ZLIB
530 gzread(f, cur_2do_pointer, obj_2d_io_size);
531 #else //ZLIB
532 fread(cur_2do_pointer, 1, obj_2d_io_size, f);
533 #endif //ZLIB
534
535 add_2d_obj(cur_2d_obj_io.file_name,cur_2d_obj_io.x_pos,cur_2d_obj_io.y_pos,
536 cur_2d_obj_io.z_pos,cur_2d_obj_io.x_rot,cur_2d_obj_io.y_rot,cur_2d_obj_io.z_rot);
537 }
538
539
540 //read the lights
541 for (i = 0; i < lights_no; i++)
542 {
543 char* cur_light_pointer = (char *)&cur_light_io;
544 #ifdef ZLIB
545 gzread(f, cur_light_pointer, lights_io_size);
546 #else //ZLIB
547 fread(cur_light_pointer, 1, lights_io_size, f);
548 #endif //ZLIB
549
550 #ifdef NEW_LIGHT_FORMAT
551 if (version == 0)
552 {
553 // Old map format, insert default values for
554 // extended light parameters
555 cur_light_io.spec_r = 255;
556 cur_light_io.spec_g = 255;
557 cur_light_io.spec_b = 255;
558
559 cur_light_io.light_dir_z_sign = 0;
560
561 cur_light_io.quadric_attenuation = 0;
562 cur_light_io.range = 0;
563 cur_light_io.cutoff = -32768;
564 cur_light_io.exponent = 0;
565
566 cur_light_io.light_dir_x = 0;
567 cur_light_io.light_dir_y = 0;
568 }
569 #endif // NEW_LIGHT_FORMAT
570
571 add_light (cur_light_io.pos_x, cur_light_io.pos_y, cur_light_io.pos_z, cur_light_io.r, cur_light_io.g, cur_light_io.b, 1.0f, 0);
572 }
573
574 //read particle systems
575 for(i=0;i<particles_no;i++)
576 {
577 char *cur_particles_pointer=(char *)&cur_particles_io;
578 #ifdef ZLIB
579 gzread(f, cur_particles_pointer,particles_io_size);
580 #else //ZLIB
581 fread(cur_particles_pointer,1,particles_io_size,f);
582 #endif //ZLIB
583
584 if (!strncmp(cur_particles_io.file_name, "ec://", 5))
585 {
586 #ifdef EYE_CANDY
587 printf("Deserializing eye candy.\n");
588 deserialize_eye_candy_effect(&cur_particles_io);
589 #else
590 LOG_ERROR("Map contains eye candy effect, but map editor is compiled without eye candy support");
591 #endif
592 }
593 else
594 {
595 add_particle_sys(cur_particles_io.file_name,cur_particles_io.x_pos,cur_particles_io.y_pos,cur_particles_io.z_pos);
596 if(particles_list[i]) particles_list[i]->ttl=-1;//Fail-safe if things mess up...
597 }
598 }
599
600 #ifdef ZLIB
601 gzclose(f);
602 #else //ZLIB
603 fclose(f);
604 #endif //ZLIB
605
606 return 1;
607 }
608
new_map(int m_x_size,int m_y_size)609 void new_map(int m_x_size,int m_y_size)
610 {
611 int i;
612 //destroy the previous map, if any
613 destroy_map();
614
615 //allocate memory for the tile map (it was destroyed)
616 tile_map=(unsigned char *)calloc(m_x_size*m_y_size, 1);
617 //now, fill the map
618 for(i=0;i<m_x_size*m_y_size;i++)tile_map[i]=1;
619 tile_map_size_x=m_x_size;
620 tile_map_size_y=m_y_size;
621
622 //allocates the memory for the heights now
623 height_map=(unsigned char *)calloc(m_x_size*m_y_size*6*6, 1);
624 //now, fill the map
625 for(i=0;i<m_x_size*m_y_size*6*6;i++)height_map[i]=11;
626
627 load_map_tiles();
628 //reset the camera coordinates
629 mx=0;
630 my=0;
631
632 dungeon=0;
633 }
634
635
636