This commit was manufactured by cvs2svn to create branch
[btb/d2x.git] / main / dumpmine.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 #ifdef HAVE_CONFIG_H
15 #include <conf.h>
16 #endif
17
18 #ifdef RCS
19 static char rcsid[] = "$Id: dumpmine.c,v 1.3 2001-10-25 02:15:56 bradleyb Exp $";
20 #endif
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <errno.h>
26
27 #include "pstypes.h"
28 #include "mono.h"
29 #include "key.h"
30 #include "gr.h"
31 #include "palette.h"
32
33 #include "inferno.h"
34 #ifdef EDITOR
35 #include "editor/editor.h"
36 #endif
37 #include "error.h"
38 #include "object.h"
39 #include "wall.h"
40 #include "gamemine.h"
41 #include "robot.h"
42 #include "player.h"
43 #include "newmenu.h"
44 #include "textures.h"
45
46 #include "bm.h"
47 #include "menu.h"
48 #include "switch.h"
49 #include "fuelcen.h"
50 #include "powerup.h"
51 #include "gameseq.h"
52 #include "polyobj.h"
53 #include "gamesave.h"
54
55
56 #ifdef EDITOR
57
58 extern ubyte bogus_data[64*64];
59 extern grs_bitmap bogus_bitmap;
60
61 //      --------------------------------------------------------------------------------
62 char    *object_types(int objnum)
63 {
64         int     type = Objects[objnum].type;
65
66         Assert((type >= 0) && (type < MAX_OBJECT_TYPES));
67         return  &Object_type_names[type];
68 }
69
70 //      --------------------------------------------------------------------------------
71 char    *object_ids(int objnum)
72 {
73         int     type = Objects[objnum].type;
74         int     id = Objects[objnum].id;
75
76         switch (type) {
77                 case OBJ_ROBOT:
78                         return &Robot_names[id];
79                         break;
80                 case OBJ_POWERUP:
81                         return &Powerup_names[id];
82                         break;
83         }
84
85         return  NULL;
86 }
87
88 void err_printf(FILE *my_file, char * format, ... )
89 {
90         va_list args;
91         char            message[256];
92
93         va_start(args, format );
94         vsprintf(message,format,args);
95         va_end(args);
96
97         mprintf((1, "%s", message));
98         fprintf(my_file, "%s", message);
99         Errors_in_mine++;
100 }
101
102 void warning_printf(FILE *my_file, char * format, ... )
103 {
104         va_list args;
105         char            message[256];
106
107         va_start(args, format );
108         vsprintf(message,format,args);
109         va_end(args);
110
111         mprintf((0, "%s", message));
112         fprintf(my_file, "%s", message);
113 }
114
115 //      -----------------------------------------------------------------------------------------------------------
116 void write_exit_text(FILE *my_file)
117 {
118         int     i, j, count;
119
120         fprintf(my_file, "-----------------------------------------------------------------------------\n");
121         fprintf(my_file, "Exit stuff\n");
122
123         //      ---------- Find exit triggers ----------
124         count=0;
125         for (i=0; i<Num_triggers; i++)
126                 if (Triggers[i].type == TT_EXIT) {
127                         int     count2;
128
129                         fprintf(my_file, "Trigger %2i, is an exit trigger with %i links.\n", i, Triggers[i].num_links);
130                         count++;
131                         if (Triggers[i].num_links != 0)
132                                 err_printf(my_file, "Error: Exit triggers must have 0 links, this one has %i links.\n", Triggers[i].num_links);
133
134                         //      Find wall pointing to this trigger.
135                         count2 = 0;
136                         for (j=0; j<Num_walls; j++)
137                                 if (Walls[j].trigger == i) {
138                                         count2++;
139                                         fprintf(my_file, "Exit trigger %i is in segment %i, on side %i, bound to wall %i\n", i, Walls[j].segnum, Walls[j].sidenum, j);
140                                 }
141                         if (count2 == 0)
142                                 err_printf(my_file, "Error: Trigger %i is not bound to any wall.\n", i);
143                         else if (count2 > 1)
144                                 err_printf(my_file, "Error: Trigger %i is bound to %i walls.\n", i, count2);
145
146                 }
147
148         if (count == 0)
149                 err_printf(my_file, "Error: No exit trigger in this mine.\n");
150         else if (count != 1)
151                 err_printf(my_file, "Error: More than one exit trigger in this mine.\n");
152         else
153                 fprintf(my_file, "\n");
154
155         //      ---------- Find exit doors ----------
156         count = 0;
157         for (i=0; i<=Highest_segment_index; i++)
158                 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
159                         if (Segments[i].children[j] == -2) {
160                                 fprintf(my_file, "Segment %3i, side %i is an exit door.\n", i, j);
161                                 count++;
162                         }
163
164         if (count == 0)
165                 err_printf(my_file, "Error: No external wall in this mine.\n");
166         else if (count != 1) {
167                 // -- warning_printf(my_file, "Warning: %i external walls in this mine.\n", count);
168                 // -- warning_printf(my_file, "(If %i are secret exits, then no problem.)\n", count-1); 
169         } else
170                 fprintf(my_file, "\n");
171 }
172
173 //      -----------------------------------------------------------------------------------------------------------
174 void write_key_text(FILE *my_file)
175 {
176         int     i;
177         int     red_count, blue_count, gold_count;
178         int     red_count2, blue_count2, gold_count2;
179         int     blue_segnum=-1, blue_sidenum=-1, red_segnum=-1, red_sidenum=-1, gold_segnum=-1, gold_sidenum=-1;
180         int     connect_side;
181
182         fprintf(my_file, "-----------------------------------------------------------------------------\n");
183         fprintf(my_file, "Key stuff:\n");
184
185         red_count = 0;
186         blue_count = 0;
187         gold_count = 0;
188
189         for (i=0; i<Num_walls; i++) {
190                 if (Walls[i].keys & KEY_BLUE) {
191                         fprintf(my_file, "Wall %i (seg=%i, side=%i) is keyed to the blue key.\n", i, Walls[i].segnum, Walls[i].sidenum);
192                         if (blue_segnum == -1) {
193                                 blue_segnum = Walls[i].segnum;
194                                 blue_sidenum = Walls[i].sidenum;
195                                 blue_count++;
196                         } else {
197                                 connect_side = find_connect_side(&Segments[Walls[i].segnum], &Segments[blue_segnum]);
198                                 if (connect_side != blue_sidenum) {
199                                         warning_printf(my_file, "Warning: This blue door at seg %i, is different than the one at seg %i, side %i\n", Walls[i].segnum, blue_segnum, blue_sidenum);
200                                         blue_count++;
201                                 }
202                         }
203                 }
204                 if (Walls[i].keys & KEY_RED) {
205                         fprintf(my_file, "Wall %i (seg=%i, side=%i) is keyed to the red key.\n", i, Walls[i].segnum, Walls[i].sidenum);
206                         if (red_segnum == -1) {
207                                 red_segnum = Walls[i].segnum;
208                                 red_sidenum = Walls[i].sidenum;
209                                 red_count++;
210                         } else {
211                                 connect_side = find_connect_side(&Segments[Walls[i].segnum], &Segments[red_segnum]);
212                                 if (connect_side != red_sidenum) {
213                                         warning_printf(my_file, "Warning: This red door at seg %i, is different than the one at seg %i, side %i\n", Walls[i].segnum, red_segnum, red_sidenum);
214                                         red_count++;
215                                 }
216                         }
217                 }
218                 if (Walls[i].keys & KEY_GOLD) {
219                         fprintf(my_file, "Wall %i (seg=%i, side=%i) is keyed to the gold key.\n", i, Walls[i].segnum, Walls[i].sidenum);
220                         if (gold_segnum == -1) {
221                                 gold_segnum = Walls[i].segnum;
222                                 gold_sidenum = Walls[i].sidenum;
223                                 gold_count++;
224                         } else {
225                                 connect_side = find_connect_side(&Segments[Walls[i].segnum], &Segments[gold_segnum]);
226                                 if (connect_side != gold_sidenum) {
227                                         warning_printf(my_file, "Warning: This gold door at seg %i, is different than the one at seg %i, side %i\n", Walls[i].segnum, gold_segnum, gold_sidenum);
228                                         gold_count++;
229                                 }
230                         }
231                 }
232         }
233
234         if (blue_count > 1)
235                 warning_printf(my_file, "Warning: %i doors are keyed to the blue key.\n", blue_count);
236
237         if (red_count > 1)
238                 warning_printf(my_file, "Warning: %i doors are keyed to the red key.\n", red_count);
239
240         if (gold_count > 1)
241                 warning_printf(my_file, "Warning: %i doors are keyed to the gold key.\n", gold_count);
242
243         red_count2 = 0;
244         blue_count2 = 0;
245         gold_count2 = 0;
246
247         for (i=0; i<=Highest_object_index; i++) {
248                 if (Objects[i].type == OBJ_POWERUP)
249                         if (Objects[i].id == POW_KEY_BLUE) {
250                                 fprintf(my_file, "The BLUE key is object %i in segment %i\n", i, Objects[i].segnum);
251                                 blue_count2++;
252                         }
253                 if (Objects[i].type == OBJ_POWERUP)
254                         if (Objects[i].id == POW_KEY_RED) {
255                                 fprintf(my_file, "The RED key is object %i in segment %i\n", i, Objects[i].segnum);
256                                 red_count2++;
257                         }
258                 if (Objects[i].type == OBJ_POWERUP)
259                         if (Objects[i].id == POW_KEY_GOLD) {
260                                 fprintf(my_file, "The GOLD key is object %i in segment %i\n", i, Objects[i].segnum);
261                                 gold_count2++;
262                         }
263
264                 if (Objects[i].contains_count) {
265                         if (Objects[i].contains_type == OBJ_POWERUP) {
266                                 switch (Objects[i].contains_id) {
267                                         case POW_KEY_BLUE:
268                                                 fprintf(my_file, "The BLUE key is contained in object %i (a %s %s) in segment %i\n", i, Object_type_names[Objects[i].type], Robot_names[Objects[i].id], Objects[i].segnum);
269                                                 blue_count2 += Objects[i].contains_count;
270                                                 break;
271                                         case POW_KEY_GOLD:
272                                                 fprintf(my_file, "The GOLD key is contained in object %i (a %s %s) in segment %i\n", i, Object_type_names[Objects[i].type], Robot_names[Objects[i].id], Objects[i].segnum);
273                                                 gold_count2 += Objects[i].contains_count;
274                                                 break;
275                                         case POW_KEY_RED:
276                                                 fprintf(my_file, "The RED key is contained in object %i (a %s %s) in segment %i\n", i, Object_type_names[Objects[i].type], Robot_names[Objects[i].id], Objects[i].segnum);
277                                                 red_count2 += Objects[i].contains_count;
278                                                 break;
279                                         default:
280                                                 break;
281                                 }
282                         }
283                 }
284         }
285
286         if (blue_count)
287                 if (blue_count2 == 0)
288                         err_printf(my_file, "Error: There is a door keyed to the blue key, but no blue key!\n");
289
290         if (red_count)
291                 if (red_count2 == 0)
292                         err_printf(my_file, "Error: There is a door keyed to the red key, but no red key!\n");
293
294         if (gold_count)
295                 if (gold_count2 == 0)
296                         err_printf(my_file, "Error: There is a door keyed to the gold key, but no gold key!\n");
297
298         if (blue_count2 > 1)
299                 err_printf(my_file, "Error: There are %i blue keys!\n", blue_count2);
300
301         if (red_count2 > 1)
302                 err_printf(my_file, "Error: There are %i red keys!\n", red_count2);
303
304         if (gold_count2 > 1)
305                 err_printf(my_file, "Error: There are %i gold keys!\n", gold_count2);
306 }
307
308 //      ------------------------------------------------------------------------------------------
309 void write_control_center_text(FILE *my_file)
310 {
311         int     i, count, objnum, count2;
312
313         fprintf(my_file, "-----------------------------------------------------------------------------\n");
314         fprintf(my_file, "Control Center stuff:\n");
315
316         count = 0;
317         for (i=0; i<=Highest_segment_index; i++)
318                 if (Segment2s[i].special == SEGMENT_IS_CONTROLCEN) {
319                         count++;
320                         fprintf(my_file, "Segment %3i is a control center.\n", i);
321                         objnum = Segments[i].objects;
322                         count2 = 0;
323                         while (objnum != -1) {
324                                 if (Objects[objnum].type == OBJ_CNTRLCEN)
325                                         count2++;
326                                 objnum = Objects[objnum].next;
327                         }
328                         if (count2 == 0)
329                                 fprintf(my_file, "No control center object in control center segment.\n");
330                         else if (count2 != 1)
331                                 fprintf(my_file, "%i control center objects in control center segment.\n", count2);
332                 }
333
334         if (count == 0)
335                 err_printf(my_file, "Error: No control center in this mine.\n");
336         else if (count != 1)
337                 err_printf(my_file, "Error: More than one control center in this mine.\n");
338 }
339
340 //      ------------------------------------------------------------------------------------------
341 void write_fuelcen_text(FILE *my_file)
342 {
343         int     i;
344
345         fprintf(my_file, "-----------------------------------------------------------------------------\n");
346         fprintf(my_file, "Fuel Center stuff: (Note: This means fuel, repair, materialize, control centers!)\n");
347
348         for (i=0; i<Num_fuelcenters; i++) {
349                 fprintf(my_file, "Fuelcenter %i: Type=%i (%s), segment = %3i\n", i, Station[i].Type, Special_names[Station[i].Type], Station[i].segnum);
350                 if (Segment2s[Station[i].segnum].special != Station[i].Type)
351                         err_printf(my_file, "Error: Conflicting data: Segment %i has special type %i (%s), expected to be %i\n", Station[i].segnum, Segment2s[Station[i].segnum].special, Special_names[Segment2s[Station[i].segnum].special], Station[i].Type);
352         }
353 }
354
355 //      ------------------------------------------------------------------------------------------
356 void write_segment_text(FILE *my_file)
357 {
358         int     i, objnum;
359
360         fprintf(my_file, "-----------------------------------------------------------------------------\n");
361         fprintf(my_file, "Segment stuff:\n");
362
363         for (i=0; i<=Highest_segment_index; i++) {
364
365                 fprintf(my_file, "Segment %4i: ", i);
366                 if (Segment2s[i].special != 0)
367                         fprintf(my_file, "special = %3i (%s), value = %3i ", Segment2s[i].special, Special_names[Segment2s[i].special], Segment2s[i].value);
368
369                 if (Segment2s[i].matcen_num != -1)
370                         fprintf(my_file, "matcen = %3i, ", Segment2s[i].matcen_num);
371                 
372                 fprintf(my_file, "\n");
373         }
374
375         for (i=0; i<=Highest_segment_index; i++) {
376                 int     depth;
377
378                 objnum = Segments[i].objects;
379                 fprintf(my_file, "Segment %4i: ", i);
380                 depth=0;
381                 if (objnum != -1) {
382                         fprintf(my_file, "Objects: ");
383                         while (objnum != -1) {
384                                 fprintf(my_file, "[%8s %8s %3i] ", object_types(objnum), object_ids(objnum), objnum);
385                                 objnum = Objects[objnum].next;
386                                 if (depth++ > 30) {
387                                         fprintf(my_file, "\nAborted after %i links\n", depth);
388                                         break;
389                                 }
390                         }
391                 }
392                 fprintf(my_file, "\n");
393         }
394 }
395
396 //      ------------------------------------------------------------------------------------------
397 //      This routine is bogus.  It assumes that all centers are matcens, which is not true.  The setting of segnum is bogus.
398 void write_matcen_text(FILE *my_file)
399 {
400         int     i, j, k;
401
402         fprintf(my_file, "-----------------------------------------------------------------------------\n");
403         fprintf(my_file, "Materialization centers:\n");
404         for (i=0; i<Num_robot_centers; i++) {
405                 int     trigger_count=0, segnum, fuelcen_num;
406
407                 fprintf(my_file, "FuelCenter[%02i].Segment = %04i  ", i, Station[i].segnum);
408                 fprintf(my_file, "Segment2[%04i].matcen_num = %02i  ", Station[i].segnum, Segment2s[Station[i].segnum].matcen_num);
409
410                 fuelcen_num = RobotCenters[i].fuelcen_num;
411                 if (Station[fuelcen_num].Type != SEGMENT_IS_ROBOTMAKER)
412                         err_printf(my_file, "Error: Matcen %i corresponds to Station %i, which has type %i (%s).\n", i, fuelcen_num, Station[fuelcen_num].Type, Special_names[Station[fuelcen_num].Type]);
413
414                 segnum = Station[fuelcen_num].segnum;
415
416                 //      Find trigger for this materialization center.
417                 for (j=0; j<Num_triggers; j++) {
418                         if (Triggers[j].type == TT_MATCEN) {
419                                 for (k=0; k<Triggers[j].num_links; k++)
420                                         if (Triggers[j].seg[k] == segnum) {
421                                                 fprintf(my_file, "Trigger = %2i  ", j );
422                                                 trigger_count++;
423                                         }
424                         }
425                 }
426                 fprintf(my_file, "\n");
427
428                 if (trigger_count == 0)
429                         err_printf(my_file, "Error: Matcen %i in segment %i has no trigger!\n", i, segnum);
430
431         }
432 }
433
434 //      ------------------------------------------------------------------------------------------
435 void write_wall_text(FILE *my_file)
436 {
437         int     i, j;
438         byte    wall_flags[MAX_WALLS];
439
440         fprintf(my_file, "-----------------------------------------------------------------------------\n");
441         fprintf(my_file, "Walls:\n");
442         for (i=0; i<Num_walls; i++) {
443                 int     segnum, sidenum;
444
445                 fprintf(my_file, "Wall %03i: seg=%3i, side=%2i, linked_wall=%3i, type=%s, flags=%4x, hps=%3i, trigger=%2i, clip_num=%2i, keys=%2i, state=%i\n", i,
446                         Walls[i].segnum, Walls[i].sidenum, Walls[i].linked_wall, Wall_names[Walls[i].type], Walls[i].flags, Walls[i].hps >> 16, Walls[i].trigger, Walls[i].clip_num, Walls[i].keys, Walls[i].state);
447
448                 if (Walls[i].trigger >= Num_triggers)
449                         fprintf(my_file, "Wall %03d points to invalid trigger %d\n",i,Walls[i].trigger);
450
451                 segnum = Walls[i].segnum;
452                 sidenum = Walls[i].sidenum;
453
454                 if (Segments[segnum].sides[sidenum].wall_num != i)
455                         err_printf(my_file, "Error: Wall %i points at segment %i, side %i, but that segment doesn't point back (it's wall_num = %i)\n", i, segnum, sidenum, Segments[segnum].sides[sidenum].wall_num);
456         }
457
458         for (i=0; i<MAX_WALLS; i++)
459                 wall_flags[i] = 0;
460
461         for (i=0; i<=Highest_segment_index; i++) {
462                 segment *segp = &Segments[i];
463                 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++) {
464                         side    *sidep = &segp->sides[j];
465                         if (sidep->wall_num != -1)
466                                 if (wall_flags[sidep->wall_num])
467                                         err_printf(my_file, "Error: Wall %i appears in two or more segments, including segment %i, side %i.\n", sidep->wall_num, i, j);
468                                 else
469                                         wall_flags[sidep->wall_num] = 1;
470                 }
471         }
472
473 }
474
475 //typedef struct trigger {
476 //      byte            type;
477 //      short           flags;
478 //      fix             value;
479 //      fix             time;
480 //      byte            link_num;
481 //      short   num_links;
482 //      short   seg[MAX_WALLS_PER_LINK];
483 //      short           side[MAX_WALLS_PER_LINK];
484 //      } trigger;
485
486 //      ------------------------------------------------------------------------------------------
487 void write_player_text(FILE *my_file)
488 {
489         int     i, num_players=0;
490
491         fprintf(my_file, "-----------------------------------------------------------------------------\n");
492         fprintf(my_file, "Players:\n");
493         for (i=0; i<=Highest_object_index; i++) {
494                 if (Objects[i].type == OBJ_PLAYER) {
495                         num_players++;
496                         fprintf(my_file, "Player %2i is object #%3i in segment #%3i.\n", Objects[i].id, i, Objects[i].segnum);
497                 }
498         }
499
500         if (num_players != MAX_PLAYERS)
501                 err_printf(my_file, "Error: %i player objects.  %i are required.\n", num_players, MAX_PLAYERS);
502         if (num_players > MAX_MULTI_PLAYERS)
503                 err_printf(my_file, "Error: %i player objects.  %i are required.\n", num_players, MAX_PLAYERS);
504 }
505
506 //      ------------------------------------------------------------------------------------------
507 void write_trigger_text(FILE *my_file)
508 {
509         int     i, j, w;
510
511         fprintf(my_file, "-----------------------------------------------------------------------------\n");
512         fprintf(my_file, "Triggers:\n");
513         for (i=0; i<Num_triggers; i++) {
514                 fprintf(my_file, "Trigger %03i: type=%02x flags=%04x, value=%08x, time=%8x, num_links=%i ", i, 
515                         Triggers[i].type, Triggers[i].flags, Triggers[i].value, Triggers[i].time, Triggers[i].num_links);
516
517                 for (j=0; j<Triggers[i].num_links; j++)
518                         fprintf(my_file, "[%03i:%i] ", Triggers[i].seg[j], Triggers[i].side[j]);
519
520                 //      Find which wall this trigger is connected to.
521                 for (w=0; w<Num_walls; w++)
522                         if (Walls[w].trigger == i)
523                                 break;
524
525                 if (w == Num_walls)
526                         err_printf(my_file, "\nError: Trigger %i is not connected to any wall, so it can never be triggered.\n", i);
527                 else
528                         fprintf(my_file, "Attached to seg:side = %i:%i, wall %i\n", Walls[w].segnum, Walls[w].sidenum, Segments[Walls[w].segnum].sides[Walls[w].sidenum].wall_num);
529
530         }
531
532 }
533
534 //      ------------------------------------------------------------------------------------------
535 void write_game_text_file(char *filename)
536 {
537         char    my_filename[128];
538         int     namelen;
539         FILE    * my_file;
540
541         Errors_in_mine = 0;
542
543         // mprintf((0, "Writing text file for mine [%s]\n", filename));
544
545         namelen = strlen(filename);
546
547         Assert (namelen > 4);
548
549         Assert (filename[namelen-4] == '.');
550
551         strcpy(my_filename, filename);
552         strcpy( &my_filename[namelen-4], ".txm");
553
554         // mprintf((0, "Writing text file [%s]\n", my_filename));
555
556         my_file = fopen( my_filename, "wt" );
557         // -- mprintf((1, "Fileno = %i\n", fileno(my_file)));
558
559         if (!my_file)   {
560                 char  ErrorMessage[200];
561
562                 sprintf( ErrorMessage, "ERROR: Unable to open %s\nErrno = %i", my_file, errno );
563                 stop_time();
564                 gr_palette_load(gr_palette);
565                 nm_messagebox( NULL, 1, "Ok", ErrorMessage );
566                 start_time();
567
568                 return;
569         }
570
571         dump_used_textures_level(my_file, 0);
572         say_totals(my_file, Gamesave_current_filename);
573
574         fprintf(my_file, "\nNumber of segments:   %4i\n", Highest_segment_index+1);
575         fprintf(my_file, "Number of objects:    %4i\n", Highest_object_index+1);
576         fprintf(my_file, "Number of walls:      %4i\n", Num_walls);
577         fprintf(my_file, "Number of open doors: %4i\n", Num_open_doors);
578         fprintf(my_file, "Number of triggers:   %4i\n", Num_triggers);
579         fprintf(my_file, "Number of matcens:    %4i\n", Num_robot_centers);
580         fprintf(my_file, "\n");
581
582         write_segment_text(my_file);
583
584         write_fuelcen_text(my_file);
585
586         write_matcen_text(my_file);
587
588         write_player_text(my_file);
589
590         write_wall_text(my_file);
591
592         write_trigger_text(my_file);
593
594         write_exit_text(my_file);
595
596         //      ---------- Find control center segment ----------
597         write_control_center_text(my_file);
598
599         //      ---------- Show keyed walls ----------
600         write_key_text(my_file);
601
602 { int r;
603         r = fclose(my_file);
604         mprintf((1, "Close value = %i\n", r));
605         if (r)
606                 Int3();
607 }
608 }
609
610 // -- //        ---------------
611 // -- //        Note: This only works for a loaded level because the objects array must be valid.
612 // -- void determine_used_textures_robots(int *tmap_buf)
613 // -- {
614 // --   int     i, objnum;
615 // --   polymodel       *po;
616 // -- 
617 // --   Assert(N_polygon_models);
618 // -- 
619 // --   for (objnum=0; objnum <= Highest_object_index; objnum++) {
620 // --           int     model_num;
621 // -- 
622 // --           if (Objects[objnum].render_type == RT_POLYOBJ) {
623 // --                   model_num = Objects[objnum].rtype.pobj_info.model_num;
624 // -- 
625 // --                   po=&Polygon_models[model_num];
626 // -- 
627 // --                   for (i=0;i<po->n_textures;i++)  {
628 // --                           int     tli;
629 // -- 
630 // --                           tli = ObjBitmaps[ObjBitmapPtrs[po->first_texture+i]];
631 // --                           Assert((tli>=0) && (tli<= Num_tmaps));
632 // --                           tmap_buf[tli]++;
633 // --                   }
634 // --           }
635 // --   }
636 // -- 
637 // -- }
638
639 // --05/17/95--//       -----------------------------------------------------------------------------
640 // --05/17/95--void determine_used_textures_level(int load_level_flag, int shareware_flag, int level_num, int *tmap_buf, int *wall_buf, byte *level_tmap_buf, int max_tmap)
641 // --05/17/95--{
642 // --05/17/95-- int     segnum, sidenum;
643 // --05/17/95-- int     i, j;
644 // --05/17/95--
645 // --05/17/95-- for (i=0; i<max_tmap; i++)
646 // --05/17/95--         tmap_buf[i] = 0;
647 // --05/17/95--
648 // --05/17/95-- if (load_level_flag) {
649 // --05/17/95--         if (shareware_flag)
650 // --05/17/95--                 load_level(Shareware_level_names[level_num]);
651 // --05/17/95--         else
652 // --05/17/95--                 load_level(Registered_level_names[level_num]);
653 // --05/17/95-- }
654 // --05/17/95--
655 // --05/17/95-- for (segnum=0; segnum<=Highest_segment_index; segnum++) {
656 // --05/17/95--         segment *segp = &Segments[segnum];
657 // --05/17/95--
658 // --05/17/95--         for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
659 // --05/17/95--                 side    *sidep = &segp->sides[sidenum];
660 // --05/17/95--
661 // --05/17/95--                 if (sidep->wall_num != -1) {
662 // --05/17/95--                         int clip_num = Walls[sidep->wall_num].clip_num;
663 // --05/17/95--                         if (clip_num != -1) {
664 // --05/17/95--
665 // --05/17/95--                                 int num_frames = WallAnims[clip_num].num_frames;
666 // --05/17/95--
667 // --05/17/95--                                 wall_buf[clip_num] = 1;
668 // --05/17/95--
669 // --05/17/95--                                 for (j=0; j<num_frames; j++) {
670 // --05/17/95--                                         int     tmap_num;
671 // --05/17/95--
672 // --05/17/95--                                         tmap_num = WallAnims[clip_num].frames[j];
673 // --05/17/95--                                         tmap_buf[tmap_num]++;
674 // --05/17/95--                                         if (level_tmap_buf[tmap_num] == -1)
675 // --05/17/95--                                                 level_tmap_buf[tmap_num] = level_num + (!shareware_flag) * NUM_SHAREWARE_LEVELS;
676 // --05/17/95--                                 }
677 // --05/17/95--                         }
678 // --05/17/95--                 }
679 // --05/17/95--
680 // --05/17/95--                 if (sidep->tmap_num >= 0)
681 // --05/17/95--                         if (sidep->tmap_num < max_tmap) {
682 // --05/17/95--                                 tmap_buf[sidep->tmap_num]++;
683 // --05/17/95--                                 if (level_tmap_buf[sidep->tmap_num] == -1)
684 // --05/17/95--                                         level_tmap_buf[sidep->tmap_num] = level_num + (!shareware_flag) * NUM_SHAREWARE_LEVELS;
685 // --05/17/95--                         } else
686 // --05/17/95--                                 Int3(); //      Error, bogus texture map.  Should not be greater than max_tmap.
687 // --05/17/95--
688 // --05/17/95--                 if ((sidep->tmap_num2 & 0x3fff) != 0)
689 // --05/17/95--                         if ((sidep->tmap_num2 & 0x3fff) < max_tmap) {
690 // --05/17/95--                                 tmap_buf[sidep->tmap_num2 & 0x3fff]++;
691 // --05/17/95--                                 if (level_tmap_buf[sidep->tmap_num2 & 0x3fff] == -1)
692 // --05/17/95--                                         level_tmap_buf[sidep->tmap_num2 & 0x3fff] = level_num + (!shareware_flag) * NUM_SHAREWARE_LEVELS;
693 // --05/17/95--                         } else
694 // --05/17/95--                                 Int3(); //      Error, bogus texture map.  Should not be greater than max_tmap.
695 // --05/17/95--         }
696 // --05/17/95-- }
697 // --05/17/95--}
698
699 //      Adam: Change NUM_ADAM_LEVELS to the number of levels.
700 #define NUM_ADAM_LEVELS 30
701
702 //      Adam: Stick the names here.
703 char *Adam_level_names[NUM_ADAM_LEVELS] = {
704         "D2LEVA-1.LVL",
705         "D2LEVA-2.LVL",
706         "D2LEVA-3.LVL",
707         "D2LEVA-4.LVL",
708         "D2LEVA-S.LVL",
709
710         "D2LEVB-1.LVL",
711         "D2LEVB-2.LVL",
712         "D2LEVB-3.LVL",
713         "D2LEVB-4.LVL",
714         "D2LEVB-S.LVL",
715
716         "D2LEVC-1.LVL",
717         "D2LEVC-2.LVL",
718         "D2LEVC-3.LVL",
719         "D2LEVC-4.LVL",
720         "D2LEVC-S.LVL",
721
722         "D2LEVD-1.LVL",
723         "D2LEVD-2.LVL",
724         "D2LEVD-3.LVL",
725         "D2LEVD-4.LVL",
726         "D2LEVD-S.LVL",
727
728         "D2LEVE-1.LVL",
729         "D2LEVE-2.LVL",
730         "D2LEVE-3.LVL",
731         "D2LEVE-4.LVL",
732         "D2LEVE-S.LVL",
733
734         "D2LEVF-1.LVL",
735         "D2LEVF-2.LVL",
736         "D2LEVF-3.LVL",
737         "D2LEVF-4.LVL",
738         "D2LEVF-S.LVL",
739 };
740
741 typedef struct BitmapFile       {
742         char                    name[15];
743 } BitmapFile;
744
745 extern BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
746
747 int     Ignore_tmap_num2_error;
748
749 //      -----------------------------------------------------------------------------
750 void determine_used_textures_level(int load_level_flag, int shareware_flag, int level_num, int *tmap_buf, int *wall_buf, byte *level_tmap_buf, int max_tmap)
751 {
752         int     segnum, sidenum, objnum=max_tmap;
753         int     i, j;
754
755         Assert(shareware_flag != -17);
756
757         for (i=0; i<MAX_BITMAP_FILES; i++)
758                 tmap_buf[i] = 0;
759
760         if (load_level_flag) {
761                 load_level(Adam_level_names[level_num]);
762         }
763
764
765         //      Process robots.
766         for (objnum=0; objnum<=Highest_object_index; objnum++) {
767                 object *objp = &Objects[objnum];
768
769                 if (objp->render_type == RT_POLYOBJ) {
770                         polymodel *po = &Polygon_models[objp->rtype.pobj_info.model_num];
771
772                         for (i=0; i<po->n_textures; i++) {
773
774                                 int     tli = ObjBitmaps[ObjBitmapPtrs[po->first_texture+i]].index;
775                                 // -- mprintf((0, "%s  ", AllBitmaps[ObjBitmaps[ObjBitmapPtrs[po->first_texture+i]].index].name));
776
777                                 if ((tli < MAX_BITMAP_FILES) && (tli >= 0)) {
778                                         tmap_buf[tli]++;
779                                         if (level_tmap_buf[tli] == -1)
780                                                 level_tmap_buf[tli] = level_num;
781                                 } else
782                                         Int3(); //      Hmm, It seems this texture is bogus!
783                         }
784
785                 }
786         }
787
788
789         Ignore_tmap_num2_error = 0;
790
791         //      Process walls and segment sides.
792         for (segnum=0; segnum<=Highest_segment_index; segnum++) {
793                 segment *segp = &Segments[segnum];
794
795                 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
796                         side    *sidep = &segp->sides[sidenum];
797
798                         if (sidep->wall_num != -1) {
799                                 int clip_num = Walls[sidep->wall_num].clip_num;
800                                 if (clip_num != -1) {
801
802                                         // -- int num_frames = WallAnims[clip_num].num_frames;
803
804                                         wall_buf[clip_num] = 1;
805
806                                         for (j=0; j<1; j++) {   //      Used to do through num_frames, but don't really want all the door01#3 stuff.
807                                                 int     tmap_num;
808
809                                                 tmap_num = Textures[WallAnims[clip_num].frames[j]].index;
810                                                 Assert((tmap_num >= 0) && (tmap_num < MAX_BITMAP_FILES));
811                                                 tmap_buf[tmap_num]++;
812                                                 if (level_tmap_buf[tmap_num] == -1)
813                                                         level_tmap_buf[tmap_num] = level_num;
814                                         }
815                                 }
816                         } else if (segp->children[sidenum] == -1) {
817
818                                 if (sidep->tmap_num >= 0)
819                                         if (sidep->tmap_num < MAX_BITMAP_FILES) {
820                                                 Assert(Textures[sidep->tmap_num].index < MAX_BITMAP_FILES);
821                                                 tmap_buf[Textures[sidep->tmap_num].index]++;
822                                                 if (level_tmap_buf[Textures[sidep->tmap_num].index] == -1)
823                                                         level_tmap_buf[Textures[sidep->tmap_num].index] = level_num;
824                                         } else
825                                                 Int3(); //      Error, bogus texture map.  Should not be greater than max_tmap.
826
827                                 if ((sidep->tmap_num2 & 0x3fff) != 0)
828                                         if ((sidep->tmap_num2 & 0x3fff) < MAX_BITMAP_FILES) {
829                                                 Assert(Textures[sidep->tmap_num2 & 0x3fff].index < MAX_BITMAP_FILES);
830                                                 tmap_buf[Textures[sidep->tmap_num2 & 0x3fff].index]++;
831                                                 if (level_tmap_buf[Textures[sidep->tmap_num2 & 0x3fff].index] == -1)
832                                                         level_tmap_buf[Textures[sidep->tmap_num2 & 0x3fff].index] = level_num;
833                                         } else {
834                                                 if (!Ignore_tmap_num2_error)
835                                                         Int3(); //      Error, bogus texture map.  Should not be greater than max_tmap.
836                                                 Ignore_tmap_num2_error = 1;
837                                                 sidep->tmap_num2 = 0;
838                                         }
839                         }
840                 }
841         }
842 }
843
844 //      -----------------------------------------------------------------------------
845 void merge_buffers(int *dest, int *src, int num)
846 {
847         int     i;
848
849         for (i=0; i<num; i++)
850                 if (src[i])
851                         dest[i] += src[i];
852 }
853
854 //      -----------------------------------------------------------------------------
855 void say_used_tmaps(FILE *my_file, int *tb)
856 {
857         int     i;
858 // -- mk, 08/14/95 --   int     count = 0;
859
860         for (i=0; i<MAX_BITMAP_FILES; i++)
861                 if (tb[i]) {
862                         fprintf(my_file, "[%3i %8s (%4i)]\n", i, AllBitmaps[i].name, tb[i]);
863 // -- mk, 08/14/95 --                   if (count++ >= 4) {
864 // -- mk, 08/14/95 --                           fprintf(my_file, "\n");
865 // -- mk, 08/14/95 --                           count = 0;
866 // -- mk, 08/14/95 --                   }
867                 }
868 }
869
870 // --05/17/95--//       -----------------------------------------------------------------------------
871 // --05/17/95--void say_used_once_tmaps(FILE *my_file, int *tb, byte *tb_lnum)
872 // --05/17/95--{
873 // --05/17/95-- int     i;
874 // --05/17/95-- char    *level_name;
875 // --05/17/95--
876 // --05/17/95-- for (i=0; i<Num_tmaps; i++)
877 // --05/17/95--         if (tb[i] == 1) {
878 // --05/17/95--                 int     level_num = tb_lnum[i];
879 // --05/17/95--                 if (level_num >= NUM_SHAREWARE_LEVELS) {
880 // --05/17/95--                         Assert((level_num - NUM_SHAREWARE_LEVELS >= 0) && (level_num - NUM_SHAREWARE_LEVELS < NUM_REGISTERED_LEVELS));
881 // --05/17/95--                         level_name = Registered_level_names[level_num - NUM_SHAREWARE_LEVELS];
882 // --05/17/95--                 } else {
883 // --05/17/95--                         Assert((level_num >= 0) && (level_num < NUM_SHAREWARE_LEVELS));
884 // --05/17/95--                         level_name = Shareware_level_names[level_num];
885 // --05/17/95--                 }
886 // --05/17/95--
887 // --05/17/95--                 fprintf(my_file, "Texture %3i %8s used only once on level %s\n", i, TmapInfo[i].filename, level_name);
888 // --05/17/95--         }
889 // --05/17/95--}
890
891 //      -----------------------------------------------------------------------------
892 void say_used_once_tmaps(FILE *my_file, int *tb, byte *tb_lnum)
893 {
894         int     i;
895         char    *level_name;
896
897         for (i=0; i<MAX_BITMAP_FILES; i++)
898                 if (tb[i] == 1) {
899                         int     level_num = tb_lnum[i];
900                         level_name = Adam_level_names[level_num];
901
902                         fprintf(my_file, "Texture %3i %8s used only once on level %s\n", i, AllBitmaps[i].name, level_name);
903                 }
904 }
905
906 //      -----------------------------------------------------------------------------
907 void say_unused_tmaps(FILE *my_file, int *tb)
908 {
909         int     i;
910         int     count = 0;
911
912         for (i=0; i<MAX_BITMAP_FILES; i++)
913                 if (!tb[i]) {
914                         if (GameBitmaps[Textures[i].index].bm_data == &bogus_data)
915                                 fprintf(my_file, "U");
916                         else
917                                 fprintf(my_file, " ");
918
919                         fprintf(my_file, "[%3i %8s] ", i, AllBitmaps[i].name);
920                         if (count++ >= 4) {
921                                 fprintf(my_file, "\n");
922                                 count = 0;
923                         }
924                 }
925 }
926
927 //      -----------------------------------------------------------------------------
928 void say_unused_walls(FILE *my_file, int *tb)
929 {
930         int     i;
931
932         for (i=0; i<Num_wall_anims; i++)
933                 if (!tb[i])
934                         fprintf(my_file, "Wall %3i is unused.\n", i);
935 }
936
937 //      -------------------------------------------------------------------------------------------------
938 say_totals(FILE *my_file, char *level_name)
939 {
940         int     i;              //, objnum;
941         int     total_robots = 0;
942         int     objects_processed = 0;
943
944         int     used_objects[MAX_OBJECTS];
945
946         fprintf(my_file, "\nLevel %s\n", level_name);
947
948         for (i=0; i<MAX_OBJECTS; i++)
949                 used_objects[i] = 0;
950
951         while (objects_processed < Highest_object_index+1) {
952                 int     j, objtype, objid, objcount, cur_obj_val, min_obj_val, min_objnum;
953
954                 //      Find new min objnum.
955                 min_obj_val = 0x7fff0000;
956                 min_objnum = -1;
957
958                 for (j=0; j<=Highest_object_index; j++) {
959                         if (!used_objects[j] && Objects[j].type!=OBJ_NONE) {
960                                 cur_obj_val = Objects[j].type * 1000 + Objects[j].id;
961                                 if (cur_obj_val < min_obj_val) {
962                                         min_objnum = j;
963                                         min_obj_val = cur_obj_val;
964                                 }
965                         }
966                 }
967                 if ((min_objnum == -1) || (Objects[min_objnum].type == 255))
968                         break;
969
970                 objcount = 0;
971
972                 objtype = Objects[min_objnum].type;
973                 objid = Objects[min_objnum].id;
974
975                 for (i=0; i<=Highest_object_index; i++) {
976                         if (!used_objects[i]) {
977
978                                 if (((Objects[i].type == objtype) && (Objects[i].id == objid)) ||
979                                                 ((Objects[i].type == objtype) && (objtype == OBJ_PLAYER)) ||
980                                                 ((Objects[i].type == objtype) && (objtype == OBJ_COOP)) ||
981                                                 ((Objects[i].type == objtype) && (objtype == OBJ_HOSTAGE))) {
982                                         if (Objects[i].type == OBJ_ROBOT)
983                                                 total_robots++;
984                                         used_objects[i] = 1;
985                                         objcount++;
986                                         objects_processed++;
987                                 }
988                         }
989                 }
990
991                 if (objcount) {
992                         fprintf(my_file, "Object: ");
993                         fprintf(my_file, "%8s %8s %3i\n", object_types(min_objnum), object_ids(min_objnum), objcount);
994                 }
995         }
996
997         fprintf(my_file, "Total robots = %3i\n", total_robots);
998 }
999
1000 int     First_dump_level = 0;
1001 int     Last_dump_level = NUM_ADAM_LEVELS-1;
1002
1003 //      -----------------------------------------------------------------------------
1004 void say_totals_all(void)
1005 {
1006         int     i;
1007         FILE    *my_file;
1008
1009         my_file = fopen( "levels.all", "wt" );
1010         // -- mprintf((1, "Fileno = %i\n", fileno(my_file)));
1011
1012         if (!my_file)   {
1013                 char  ErrorMessage[200];
1014
1015                 sprintf( ErrorMessage, "ERROR: Unable to open levels.all\nErrno=%i", errno );
1016                 stop_time();
1017                 gr_palette_load(gr_palette);
1018                 nm_messagebox( NULL, 1, "Ok", ErrorMessage );
1019                 start_time();
1020
1021                 return;
1022         }
1023
1024         for (i=First_dump_level; i<=Last_dump_level; i++) {
1025                 mprintf((0, "Level %i\n", i+1));
1026                 load_level(Adam_level_names[i]);
1027                 say_totals(my_file, Adam_level_names[i]);
1028         }
1029
1030 //--05/17/95--  for (i=0; i<NUM_SHAREWARE_LEVELS; i++) {
1031 //--05/17/95--          mprintf((0, "Level %i\n", i+1));
1032 //--05/17/95--          load_level(Shareware_level_names[i]);
1033 //--05/17/95--          say_totals(my_file, Shareware_level_names[i]);
1034 //--05/17/95--  }
1035 //--05/17/95--
1036 //--05/17/95--  for (i=0; i<NUM_REGISTERED_LEVELS; i++) {
1037 //--05/17/95--          mprintf((0, "Level %i\n", i+1+NUM_SHAREWARE_LEVELS));
1038 //--05/17/95--          load_level(Registered_level_names[i]);
1039 //--05/17/95--          say_totals(my_file, Registered_level_names[i]);
1040 //--05/17/95--  }
1041
1042         fclose(my_file);
1043
1044 }
1045
1046 void dump_used_textures_level(FILE *my_file, int level_num)
1047 {
1048         int     i;
1049         int     temp_tmap_buf[MAX_BITMAP_FILES];
1050         int     perm_tmap_buf[MAX_BITMAP_FILES];
1051         byte    level_tmap_buf[MAX_BITMAP_FILES];
1052         int     temp_wall_buf[MAX_BITMAP_FILES];
1053         int     perm_wall_buf[MAX_BITMAP_FILES];
1054
1055         for (i=0; i<MAX_BITMAP_FILES; i++) {
1056                 perm_tmap_buf[i] = 0;
1057                 level_tmap_buf[i] = -1;
1058         }
1059
1060         for (i=0; i<MAX_BITMAP_FILES; i++) {
1061                 perm_wall_buf[i] = 0;
1062         }
1063
1064         determine_used_textures_level(0, 1, level_num, temp_tmap_buf, temp_wall_buf, level_tmap_buf, MAX_BITMAP_FILES);
1065 // --   determine_used_textures_robots(temp_tmap_buf);
1066         fprintf(my_file, "\nTextures used in [%s]\n", Gamesave_current_filename);
1067         say_used_tmaps(my_file, temp_tmap_buf);
1068 }
1069
1070 FILE    *my_file;
1071
1072 //      -----------------------------------------------------------------------------
1073 void dump_used_textures_all(void)
1074 {
1075         int     i;
1076         int     temp_tmap_buf[MAX_BITMAP_FILES];
1077         int     perm_tmap_buf[MAX_BITMAP_FILES];
1078         byte    level_tmap_buf[MAX_BITMAP_FILES];
1079         int     temp_wall_buf[MAX_BITMAP_FILES];
1080         int     perm_wall_buf[MAX_BITMAP_FILES];
1081
1082 say_totals_all();
1083
1084         my_file = fopen( "textures.dmp", "wt" );
1085         // -- mprintf((1, "Fileno = %i\n", fileno(my_file)));
1086
1087         if (!my_file)   {
1088                 char  ErrorMessage[200];
1089
1090                 sprintf( ErrorMessage, "ERROR: Can't open textures.dmp\nErrno=%i", errno);
1091                 stop_time();
1092                 gr_palette_load(gr_palette);
1093                 nm_messagebox( NULL, 1, "Ok", ErrorMessage );
1094                 start_time();
1095
1096                 return;
1097         }
1098
1099         for (i=0; i<MAX_BITMAP_FILES; i++) {
1100                 perm_tmap_buf[i] = 0;
1101                 level_tmap_buf[i] = -1;
1102         }
1103
1104         for (i=0; i<MAX_BITMAP_FILES; i++) {
1105                 perm_wall_buf[i] = 0;
1106         }
1107
1108 // --05/17/95-- for (i=0; i<NUM_SHAREWARE_LEVELS; i++) {
1109 // --05/17/95--         determine_used_textures_level(1, 1, i, temp_tmap_buf, temp_wall_buf, level_tmap_buf, MAX_BITMAP_FILES);
1110 // --05/17/95--         fprintf(my_file, "\nTextures used in [%s]\n", Shareware_level_names[i]);
1111 // --05/17/95--         say_used_tmaps(my_file, temp_tmap_buf);
1112 // --05/17/95--         merge_buffers(perm_tmap_buf, temp_tmap_buf, MAX_BITMAP_FILES);
1113 // --05/17/95--         merge_buffers(perm_wall_buf, temp_wall_buf, MAX_BITMAP_FILES);
1114 // --05/17/95-- }
1115 // --05/17/95--
1116 // --05/17/95-- fprintf(my_file, "\n\nUsed textures in all shareware mines:\n");
1117 // --05/17/95-- say_used_tmaps(my_file, perm_tmap_buf);
1118 // --05/17/95--
1119 // --05/17/95-- fprintf(my_file, "\nUnused textures in all shareware mines:\n");
1120 // --05/17/95-- say_unused_tmaps(my_file, perm_tmap_buf);
1121 // --05/17/95--
1122 // --05/17/95-- fprintf(my_file, "\nTextures used exactly once in all shareware mines:\n");
1123 // --05/17/95-- say_used_once_tmaps(my_file, perm_tmap_buf, level_tmap_buf);
1124 // --05/17/95--
1125 // --05/17/95-- fprintf(my_file, "\nWall anims (eg, doors) unused in all shareware mines:\n");
1126 // --05/17/95-- say_unused_walls(my_file, perm_wall_buf);
1127
1128 // --05/17/95-- for (i=0; i<NUM_REGISTERED_LEVELS; i++) {
1129 // --05/17/95--         determine_used_textures_level(1, 0, i, temp_tmap_buf, temp_wall_buf, level_tmap_buf, MAX_BITMAP_FILES);
1130 // --05/17/95--         fprintf(my_file, "\nTextures used in [%s]\n", Registered_level_names[i]);
1131 // --05/17/95--         say_used_tmaps(my_file, temp_tmap_buf);
1132 // --05/17/95--         merge_buffers(perm_tmap_buf, temp_tmap_buf, MAX_BITMAP_FILES);
1133 // --05/17/95-- }
1134 // --05/17/95--
1135 // --05/17/95-- fprintf(my_file, "\n\nUsed textures in all (including registered) mines:\n");
1136 // --05/17/95-- say_used_tmaps(my_file, perm_tmap_buf);
1137 // --05/17/95--
1138 // --05/17/95-- fprintf(my_file, "\nUnused textures in all (including registered) mines:\n");
1139 // --05/17/95-- say_unused_tmaps(my_file, perm_tmap_buf);
1140
1141         for (i=First_dump_level; i<=Last_dump_level; i++) {
1142                 determine_used_textures_level(1, 0, i, temp_tmap_buf, temp_wall_buf, level_tmap_buf, MAX_BITMAP_FILES);
1143                 fprintf(my_file, "\nTextures used in [%s]\n", Adam_level_names[i]);
1144                 say_used_tmaps(my_file, temp_tmap_buf);
1145                 merge_buffers(perm_tmap_buf, temp_tmap_buf, MAX_BITMAP_FILES);
1146         }
1147
1148         fprintf(my_file, "\n\nUsed textures in all (including registered) mines:\n");
1149         say_used_tmaps(my_file, perm_tmap_buf);
1150
1151         fprintf(my_file, "\nUnused textures in all (including registered) mines:\n");
1152         say_unused_tmaps(my_file, perm_tmap_buf);
1153
1154         fclose(my_file);
1155 }
1156
1157 #endif