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