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