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.
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.
36 #include "editor/editor.h"
43 extern ubyte bogus_data[64*64];
45 void dump_used_textures_level(FILE *my_file, int level_num);
46 static void say_totals(FILE *my_file, const char *level_name);
48 // ----------------------------------------------------------------------------
49 char *object_types(int objnum)
51 int type = Objects[objnum].type;
53 Assert((type >= 0) && (type < MAX_OBJECT_TYPES));
54 return Object_type_names[type];
57 // ----------------------------------------------------------------------------
58 char *object_ids(int objnum)
60 int type = Objects[objnum].type;
61 int id = Objects[objnum].id;
65 return Robot_names[id];
68 return Powerup_names[id];
75 void err_printf(FILE *my_file, char * format, ... )
80 va_start(args, format );
81 vsprintf(message,format,args);
84 mprintf((1, "%s", message));
85 fprintf(my_file, "%s", message);
89 void warning_printf(FILE *my_file, char * format, ... )
94 va_start(args, format );
95 vsprintf(message,format,args);
98 mprintf((0, "%s", message));
99 fprintf(my_file, "%s", message);
102 // ----------------------------------------------------------------------------
103 void write_exit_text(FILE *my_file)
107 fprintf(my_file, "-----------------------------------------------------------------------------\n");
108 fprintf(my_file, "Exit stuff\n");
110 // ---------- Find exit triggers ----------
112 for (i=0; i<Num_triggers; i++)
113 if (Triggers[i].type == TT_EXIT) {
116 fprintf(my_file, "Trigger %2i, is an exit trigger with %i links.\n", i, Triggers[i].num_links);
118 if (Triggers[i].num_links != 0)
119 err_printf(my_file, "Error: Exit triggers must have 0 links, this one has %i links.\n", Triggers[i].num_links);
121 // Find wall pointing to this trigger.
123 for (j=0; j<Num_walls; j++)
124 if (Walls[j].trigger == i) {
126 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);
129 err_printf(my_file, "Error: Trigger %i is not bound to any wall.\n", i);
131 err_printf(my_file, "Error: Trigger %i is bound to %i walls.\n", i, count2);
136 err_printf(my_file, "Error: No exit trigger in this mine.\n");
138 err_printf(my_file, "Error: More than one exit trigger in this mine.\n");
140 fprintf(my_file, "\n");
142 // ---------- Find exit doors ----------
144 for (i=0; i<=Highest_segment_index; i++)
145 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
146 if (Segments[i].children[j] == -2) {
147 fprintf(my_file, "Segment %3i, side %i is an exit door.\n", i, j);
152 err_printf(my_file, "Error: No external wall in this mine.\n");
153 else if (count != 1) {
154 // -- warning_printf(my_file, "Warning: %i external walls in this mine.\n", count);
155 // -- warning_printf(my_file, "(If %i are secret exits, then no problem.)\n", count-1);
157 fprintf(my_file, "\n");
160 // ----------------------------------------------------------------------------
161 void write_key_text(FILE *my_file)
164 int red_count, blue_count, gold_count;
165 int red_count2, blue_count2, gold_count2;
166 int blue_segnum=-1, blue_sidenum=-1, red_segnum=-1, red_sidenum=-1, gold_segnum=-1, gold_sidenum=-1;
169 fprintf(my_file, "-----------------------------------------------------------------------------\n");
170 fprintf(my_file, "Key stuff:\n");
176 for (i=0; i<Num_walls; i++) {
177 if (Walls[i].keys & KEY_BLUE) {
178 fprintf(my_file, "Wall %i (seg=%i, side=%i) is keyed to the blue key.\n", i, Walls[i].segnum, Walls[i].sidenum);
179 if (blue_segnum == -1) {
180 blue_segnum = Walls[i].segnum;
181 blue_sidenum = Walls[i].sidenum;
184 connect_side = find_connect_side(&Segments[Walls[i].segnum], &Segments[blue_segnum]);
185 if (connect_side != blue_sidenum) {
186 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);
191 if (Walls[i].keys & KEY_RED) {
192 fprintf(my_file, "Wall %i (seg=%i, side=%i) is keyed to the red key.\n", i, Walls[i].segnum, Walls[i].sidenum);
193 if (red_segnum == -1) {
194 red_segnum = Walls[i].segnum;
195 red_sidenum = Walls[i].sidenum;
198 connect_side = find_connect_side(&Segments[Walls[i].segnum], &Segments[red_segnum]);
199 if (connect_side != red_sidenum) {
200 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);
205 if (Walls[i].keys & KEY_GOLD) {
206 fprintf(my_file, "Wall %i (seg=%i, side=%i) is keyed to the gold key.\n", i, Walls[i].segnum, Walls[i].sidenum);
207 if (gold_segnum == -1) {
208 gold_segnum = Walls[i].segnum;
209 gold_sidenum = Walls[i].sidenum;
212 connect_side = find_connect_side(&Segments[Walls[i].segnum], &Segments[gold_segnum]);
213 if (connect_side != gold_sidenum) {
214 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);
222 warning_printf(my_file, "Warning: %i doors are keyed to the blue key.\n", blue_count);
225 warning_printf(my_file, "Warning: %i doors are keyed to the red key.\n", red_count);
228 warning_printf(my_file, "Warning: %i doors are keyed to the gold key.\n", gold_count);
234 for (i=0; i<=Highest_object_index; i++) {
235 if (Objects[i].type == OBJ_POWERUP)
236 if (Objects[i].id == POW_KEY_BLUE) {
237 fprintf(my_file, "The BLUE key is object %i in segment %i\n", i, Objects[i].segnum);
240 if (Objects[i].type == OBJ_POWERUP)
241 if (Objects[i].id == POW_KEY_RED) {
242 fprintf(my_file, "The RED key is object %i in segment %i\n", i, Objects[i].segnum);
245 if (Objects[i].type == OBJ_POWERUP)
246 if (Objects[i].id == POW_KEY_GOLD) {
247 fprintf(my_file, "The GOLD key is object %i in segment %i\n", i, Objects[i].segnum);
251 if (Objects[i].contains_count) {
252 if (Objects[i].contains_type == OBJ_POWERUP) {
253 switch (Objects[i].contains_id) {
255 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);
256 blue_count2 += Objects[i].contains_count;
259 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);
260 gold_count2 += Objects[i].contains_count;
263 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);
264 red_count2 += Objects[i].contains_count;
274 if (blue_count2 == 0)
275 err_printf(my_file, "Error: There is a door keyed to the blue key, but no blue key!\n");
279 err_printf(my_file, "Error: There is a door keyed to the red key, but no red key!\n");
282 if (gold_count2 == 0)
283 err_printf(my_file, "Error: There is a door keyed to the gold key, but no gold key!\n");
286 err_printf(my_file, "Error: There are %i blue keys!\n", blue_count2);
289 err_printf(my_file, "Error: There are %i red keys!\n", red_count2);
292 err_printf(my_file, "Error: There are %i gold keys!\n", gold_count2);
295 // ----------------------------------------------------------------------------
296 void write_control_center_text(FILE *my_file)
298 int i, count, objnum, count2;
300 fprintf(my_file, "-----------------------------------------------------------------------------\n");
301 fprintf(my_file, "Control Center stuff:\n");
304 for (i=0; i<=Highest_segment_index; i++)
305 if (Segment2s[i].special == SEGMENT_IS_CONTROLCEN) {
307 fprintf(my_file, "Segment %3i is a control center.\n", i);
308 objnum = Segments[i].objects;
310 while (objnum != -1) {
311 if (Objects[objnum].type == OBJ_CNTRLCEN)
313 objnum = Objects[objnum].next;
316 fprintf(my_file, "No control center object in control center segment.\n");
317 else if (count2 != 1)
318 fprintf(my_file, "%i control center objects in control center segment.\n", count2);
322 err_printf(my_file, "Error: No control center in this mine.\n");
324 err_printf(my_file, "Error: More than one control center in this mine.\n");
327 // ----------------------------------------------------------------------------
328 void write_fuelcen_text(FILE *my_file)
332 fprintf(my_file, "-----------------------------------------------------------------------------\n");
333 fprintf(my_file, "Fuel Center stuff: (Note: This means fuel, repair, materialize, control centers!)\n");
335 for (i=0; i<Num_fuelcenters; i++) {
336 fprintf(my_file, "Fuelcenter %i: Type=%i (%s), segment = %3i\n", i, Station[i].Type, Special_names[Station[i].Type], Station[i].segnum);
337 if (Segment2s[Station[i].segnum].special != Station[i].Type)
338 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);
342 // ----------------------------------------------------------------------------
343 void write_segment_text(FILE *my_file)
347 fprintf(my_file, "-----------------------------------------------------------------------------\n");
348 fprintf(my_file, "Segment stuff:\n");
350 for (i=0; i<=Highest_segment_index; i++) {
352 fprintf(my_file, "Segment %4i: ", i);
353 if (Segment2s[i].special != 0)
354 fprintf(my_file, "special = %3i (%s), value = %3i ", Segment2s[i].special, Special_names[Segment2s[i].special], Segment2s[i].value);
356 if (Segment2s[i].matcen_num != -1)
357 fprintf(my_file, "matcen = %3i, ", Segment2s[i].matcen_num);
359 fprintf(my_file, "\n");
362 for (i=0; i<=Highest_segment_index; i++) {
365 objnum = Segments[i].objects;
366 fprintf(my_file, "Segment %4i: ", i);
369 fprintf(my_file, "Objects: ");
370 while (objnum != -1) {
371 fprintf(my_file, "[%8s %8s %3i] ", object_types(objnum), object_ids(objnum), objnum);
372 objnum = Objects[objnum].next;
374 fprintf(my_file, "\nAborted after %i links\n", depth);
379 fprintf(my_file, "\n");
383 // ----------------------------------------------------------------------------
384 // This routine is bogus. It assumes that all centers are matcens,
385 // which is not true. The setting of segnum is bogus.
386 void write_matcen_text(FILE *my_file)
390 fprintf(my_file, "-----------------------------------------------------------------------------\n");
391 fprintf(my_file, "Materialization centers:\n");
392 for (i=0; i<Num_robot_centers; i++) {
393 int trigger_count=0, segnum, fuelcen_num;
395 fprintf(my_file, "FuelCenter[%02i].Segment = %04i ", i, Station[i].segnum);
396 fprintf(my_file, "Segment2[%04i].matcen_num = %02i ", Station[i].segnum, Segment2s[Station[i].segnum].matcen_num);
398 fuelcen_num = RobotCenters[i].fuelcen_num;
399 if (Station[fuelcen_num].Type != SEGMENT_IS_ROBOTMAKER)
400 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]);
402 segnum = Station[fuelcen_num].segnum;
404 // Find trigger for this materialization center.
405 for (j=0; j<Num_triggers; j++) {
406 if (Triggers[j].type == TT_MATCEN) {
407 for (k=0; k<Triggers[j].num_links; k++)
408 if (Triggers[j].seg[k] == segnum) {
409 fprintf(my_file, "Trigger = %2i ", j );
414 fprintf(my_file, "\n");
416 if (trigger_count == 0)
417 err_printf(my_file, "Error: Matcen %i in segment %i has no trigger!\n", i, segnum);
422 // ----------------------------------------------------------------------------
423 void write_wall_text(FILE *my_file)
426 sbyte wall_flags[MAX_WALLS];
428 fprintf(my_file, "-----------------------------------------------------------------------------\n");
429 fprintf(my_file, "Walls:\n");
430 for (i=0; i<Num_walls; i++) {
433 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,
434 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);
436 if (Walls[i].trigger >= Num_triggers)
437 fprintf(my_file, "Wall %03d points to invalid trigger %d\n",i,Walls[i].trigger);
439 segnum = Walls[i].segnum;
440 sidenum = Walls[i].sidenum;
442 if (Segments[segnum].sides[sidenum].wall_num != i)
443 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);
446 for (i=0; i<MAX_WALLS; i++)
449 for (i=0; i<=Highest_segment_index; i++) {
450 segment *segp = &Segments[i];
451 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++) {
452 side *sidep = &segp->sides[j];
453 if (sidep->wall_num != -1)
455 if (wall_flags[sidep->wall_num])
456 err_printf(my_file, "Error: Wall %i appears in two or more segments, including segment %i, side %i.\n", sidep->wall_num, i, j);
458 wall_flags[sidep->wall_num] = 1;
465 //typedef struct trigger {
472 // short seg[MAX_WALLS_PER_LINK];
473 // short side[MAX_WALLS_PER_LINK];
476 // ----------------------------------------------------------------------------
477 void write_player_text(FILE *my_file)
479 int i, num_players=0;
481 fprintf(my_file, "-----------------------------------------------------------------------------\n");
482 fprintf(my_file, "Players:\n");
483 for (i=0; i<=Highest_object_index; i++) {
484 if (Objects[i].type == OBJ_PLAYER) {
486 fprintf(my_file, "Player %2i is object #%3i in segment #%3i.\n", Objects[i].id, i, Objects[i].segnum);
490 if (num_players != MAX_PLAYERS)
491 err_printf(my_file, "Error: %i player objects. %i are required.\n", num_players, MAX_PLAYERS);
492 if (num_players > MAX_MULTI_PLAYERS)
493 err_printf(my_file, "Error: %i player objects. %i are required.\n", num_players, MAX_PLAYERS);
496 // ----------------------------------------------------------------------------
497 void write_trigger_text(FILE *my_file)
501 fprintf(my_file, "-----------------------------------------------------------------------------\n");
502 fprintf(my_file, "Triggers:\n");
503 for (i=0; i<Num_triggers; i++) {
504 fprintf(my_file, "Trigger %03i: type=%02x flags=%04x, value=%08x, time=%8x, num_links=%i ", i,
505 Triggers[i].type, Triggers[i].flags, Triggers[i].value, Triggers[i].time, Triggers[i].num_links);
507 for (j=0; j<Triggers[i].num_links; j++)
508 fprintf(my_file, "[%03i:%i] ", Triggers[i].seg[j], Triggers[i].side[j]);
510 // Find which wall this trigger is connected to.
511 for (w=0; w<Num_walls; w++)
512 if (Walls[w].trigger == i)
516 err_printf(my_file, "\nError: Trigger %i is not connected to any wall, so it can never be triggered.\n", i);
518 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);
524 // ----------------------------------------------------------------------------
525 void write_game_text_file(char *filename)
527 char my_filename[128];
533 // mprintf((0, "Writing text file for mine [%s]\n", filename));
535 namelen = (int)strlen(filename);
537 Assert (namelen > 4);
539 Assert (filename[namelen-4] == '.');
541 strcpy(my_filename, filename);
542 strcpy( &my_filename[namelen-4], ".txm");
544 // mprintf((0, "Writing text file [%s]\n", my_filename));
546 my_file = fopen( my_filename, "wt" );
547 // -- mprintf((1, "Fileno = %i\n", fileno(my_file)));
550 char ErrorMessage[200];
552 sprintf(ErrorMessage, "ERROR: Unable to open %s\nErrno = %i", my_filename, errno);
554 gr_palette_load(gr_palette);
555 nm_messagebox( NULL, 1, "Ok", ErrorMessage );
561 dump_used_textures_level(my_file, 0);
562 say_totals(my_file, Gamesave_current_filename);
564 fprintf(my_file, "\nNumber of segments: %4i\n", Highest_segment_index+1);
565 fprintf(my_file, "Number of objects: %4i\n", Highest_object_index+1);
566 fprintf(my_file, "Number of walls: %4i\n", Num_walls);
567 fprintf(my_file, "Number of open doors: %4i\n", Num_open_doors);
568 fprintf(my_file, "Number of triggers: %4i\n", Num_triggers);
569 fprintf(my_file, "Number of matcens: %4i\n", Num_robot_centers);
570 fprintf(my_file, "\n");
572 write_segment_text(my_file);
574 write_fuelcen_text(my_file);
576 write_matcen_text(my_file);
578 write_player_text(my_file);
580 write_wall_text(my_file);
582 write_trigger_text(my_file);
584 write_exit_text(my_file);
586 // ---------- Find control center segment ----------
587 write_control_center_text(my_file);
589 // ---------- Show keyed walls ----------
590 write_key_text(my_file);
594 mprintf((1, "Close value = %i\n", r));
600 // -- // ---------------
601 // -- // Note: This only works for a loaded level because the objects array must be valid.
602 // -- void determine_used_textures_robots(int *tmap_buf)
607 // -- Assert(N_polygon_models);
609 // -- for (objnum=0; objnum <= Highest_object_index; objnum++) {
612 // -- if (Objects[objnum].render_type == RT_POLYOBJ) {
613 // -- model_num = Objects[objnum].rtype.pobj_info.model_num;
615 // -- po=&Polygon_models[model_num];
617 // -- for (i=0;i<po->n_textures;i++) {
620 // -- tli = ObjBitmaps[ObjBitmapPtrs[po->first_texture+i]];
621 // -- Assert((tli>=0) && (tli<= Num_tmaps));
622 // -- tmap_buf[tli]++;
629 // --05/17/95--// -----------------------------------------------------------------------------
630 // --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)
632 // --05/17/95-- int segnum, sidenum;
633 // --05/17/95-- int i, j;
635 // --05/17/95-- for (i=0; i<max_tmap; i++)
636 // --05/17/95-- tmap_buf[i] = 0;
638 // --05/17/95-- if (load_level_flag) {
639 // --05/17/95-- if (shareware_flag)
640 // --05/17/95-- load_level(Shareware_level_names[level_num]);
642 // --05/17/95-- load_level(Registered_level_names[level_num]);
645 // --05/17/95-- for (segnum=0; segnum<=Highest_segment_index; segnum++) {
646 // --05/17/95-- segment *segp = &Segments[segnum];
648 // --05/17/95-- for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
649 // --05/17/95-- side *sidep = &segp->sides[sidenum];
651 // --05/17/95-- if (sidep->wall_num != -1) {
652 // --05/17/95-- int clip_num = Walls[sidep->wall_num].clip_num;
653 // --05/17/95-- if (clip_num != -1) {
655 // --05/17/95-- int num_frames = WallAnims[clip_num].num_frames;
657 // --05/17/95-- wall_buf[clip_num] = 1;
659 // --05/17/95-- for (j=0; j<num_frames; j++) {
660 // --05/17/95-- int tmap_num;
662 // --05/17/95-- tmap_num = WallAnims[clip_num].frames[j];
663 // --05/17/95-- tmap_buf[tmap_num]++;
664 // --05/17/95-- if (level_tmap_buf[tmap_num] == -1)
665 // --05/17/95-- level_tmap_buf[tmap_num] = level_num + (!shareware_flag) * NUM_SHAREWARE_LEVELS;
670 // --05/17/95-- if (sidep->tmap_num >= 0)
671 // --05/17/95-- if (sidep->tmap_num < max_tmap) {
672 // --05/17/95-- tmap_buf[sidep->tmap_num]++;
673 // --05/17/95-- if (level_tmap_buf[sidep->tmap_num] == -1)
674 // --05/17/95-- level_tmap_buf[sidep->tmap_num] = level_num + (!shareware_flag) * NUM_SHAREWARE_LEVELS;
675 // --05/17/95-- } else
676 // --05/17/95-- Int3(); // Error, bogus texture map. Should not be greater than max_tmap.
678 // --05/17/95-- if ((sidep->tmap_num2 & 0x3fff) != 0)
679 // --05/17/95-- if ((sidep->tmap_num2 & 0x3fff) < max_tmap) {
680 // --05/17/95-- tmap_buf[sidep->tmap_num2 & 0x3fff]++;
681 // --05/17/95-- if (level_tmap_buf[sidep->tmap_num2 & 0x3fff] == -1)
682 // --05/17/95-- level_tmap_buf[sidep->tmap_num2 & 0x3fff] = level_num + (!shareware_flag) * NUM_SHAREWARE_LEVELS;
683 // --05/17/95-- } else
684 // --05/17/95-- Int3(); // Error, bogus texture map. Should not be greater than max_tmap.
689 // Adam: Change NUM_ADAM_LEVELS to the number of levels.
690 #define NUM_ADAM_LEVELS 30
692 // Adam: Stick the names here.
693 static const char *const Adam_level_names[NUM_ADAM_LEVELS] = {
731 typedef struct BitmapFile {
735 extern BitmapFile AllBitmaps[ MAX_BITMAP_FILES ];
737 int Ignore_tmap_num2_error;
739 // ----------------------------------------------------------------------------
740 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)
742 int segnum, sidenum, objnum=max_tmap;
745 Assert(shareware_flag != -17);
747 for (i=0; i<MAX_BITMAP_FILES; i++)
750 if (load_level_flag) {
751 load_level(Adam_level_names[level_num]);
756 for (objnum=0; objnum<=Highest_object_index; objnum++) {
757 object *objp = &Objects[objnum];
759 if (objp->render_type == RT_POLYOBJ) {
760 polymodel *po = &Polygon_models[objp->rtype.pobj_info.model_num];
762 for (i=0; i<po->n_textures; i++) {
764 int tli = ObjBitmaps[ObjBitmapPtrs[po->first_texture+i]].index;
765 // -- mprintf((0, "%s ", AllBitmaps[ObjBitmaps[ObjBitmapPtrs[po->first_texture+i]].index].name));
767 if ((tli < MAX_BITMAP_FILES) && (tli >= 0)) {
769 if (level_tmap_buf[tli] == -1)
770 level_tmap_buf[tli] = level_num;
772 Int3(); // Hmm, It seems this texture is bogus!
779 Ignore_tmap_num2_error = 0;
781 // Process walls and segment sides.
782 for (segnum=0; segnum<=Highest_segment_index; segnum++) {
783 segment *segp = &Segments[segnum];
785 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
786 side *sidep = &segp->sides[sidenum];
788 if (sidep->wall_num != -1) {
789 int clip_num = Walls[sidep->wall_num].clip_num;
790 if (clip_num != -1) {
792 // -- int num_frames = WallAnims[clip_num].num_frames;
794 wall_buf[clip_num] = 1;
796 for (j=0; j<1; j++) { // Used to do through num_frames, but don't really want all the door01#3 stuff.
799 tmap_num = Textures[WallAnims[clip_num].frames[j]].index;
800 Assert((tmap_num >= 0) && (tmap_num < MAX_BITMAP_FILES));
801 tmap_buf[tmap_num]++;
802 if (level_tmap_buf[tmap_num] == -1)
803 level_tmap_buf[tmap_num] = level_num;
806 } else if (segp->children[sidenum] == -1) {
808 if (sidep->tmap_num >= 0)
810 if (sidep->tmap_num < MAX_BITMAP_FILES) {
811 Assert(Textures[sidep->tmap_num].index < MAX_BITMAP_FILES);
812 tmap_buf[Textures[sidep->tmap_num].index]++;
813 if (level_tmap_buf[Textures[sidep->tmap_num].index] == -1)
814 level_tmap_buf[Textures[sidep->tmap_num].index] = level_num;
816 Int3(); // Error, bogus texture map. Should not be greater than max_tmap.
819 if ((sidep->tmap_num2 & 0x3fff) != 0)
821 if ((sidep->tmap_num2 & 0x3fff) < MAX_BITMAP_FILES) {
822 Assert(Textures[sidep->tmap_num2 & 0x3fff].index < MAX_BITMAP_FILES);
823 tmap_buf[Textures[sidep->tmap_num2 & 0x3fff].index]++;
824 if (level_tmap_buf[Textures[sidep->tmap_num2 & 0x3fff].index] == -1)
825 level_tmap_buf[Textures[sidep->tmap_num2 & 0x3fff].index] = level_num;
827 if (!Ignore_tmap_num2_error)
828 Int3(); // Error, bogus texture map. Should not be greater than max_tmap.
829 Ignore_tmap_num2_error = 1;
830 sidep->tmap_num2 = 0;
838 // ----------------------------------------------------------------------------
839 void merge_buffers(int *dest, int *src, int num)
843 for (i=0; i<num; i++)
848 // ----------------------------------------------------------------------------
849 void say_used_tmaps(FILE *my_file, int *tb)
852 // -- mk, 08/14/95 -- int count = 0;
854 for (i=0; i<MAX_BITMAP_FILES; i++)
856 fprintf(my_file, "[%3i %8s (%4i)]\n", i, AllBitmaps[i].name, tb[i]);
857 // -- mk, 08/14/95 -- if (count++ >= 4) {
858 // -- mk, 08/14/95 -- fprintf(my_file, "\n");
859 // -- mk, 08/14/95 -- count = 0;
860 // -- mk, 08/14/95 -- }
864 // --05/17/95--// -----------------------------------------------------------------------------
865 // --05/17/95--void say_used_once_tmaps(FILE *my_file, int *tb, sbyte *tb_lnum)
867 // --05/17/95-- int i;
868 // --05/17/95-- char *level_name;
870 // --05/17/95-- for (i=0; i<Num_tmaps; i++)
871 // --05/17/95-- if (tb[i] == 1) {
872 // --05/17/95-- int level_num = tb_lnum[i];
873 // --05/17/95-- if (level_num >= NUM_SHAREWARE_LEVELS) {
874 // --05/17/95-- Assert((level_num - NUM_SHAREWARE_LEVELS >= 0) && (level_num - NUM_SHAREWARE_LEVELS < NUM_REGISTERED_LEVELS));
875 // --05/17/95-- level_name = Registered_level_names[level_num - NUM_SHAREWARE_LEVELS];
876 // --05/17/95-- } else {
877 // --05/17/95-- Assert((level_num >= 0) && (level_num < NUM_SHAREWARE_LEVELS));
878 // --05/17/95-- level_name = Shareware_level_names[level_num];
881 // --05/17/95-- fprintf(my_file, "Texture %3i %8s used only once on level %s\n", i, TmapInfo[i].filename, level_name);
885 // ----------------------------------------------------------------------------
886 void say_used_once_tmaps(FILE *my_file, int *tb, sbyte *tb_lnum)
889 const char *level_name;
891 for (i=0; i<MAX_BITMAP_FILES; i++)
893 int level_num = tb_lnum[i];
894 level_name = Adam_level_names[level_num];
896 fprintf(my_file, "Texture %3i %8s used only once on level %s\n", i, AllBitmaps[i].name, level_name);
900 // ----------------------------------------------------------------------------
901 void say_unused_tmaps(FILE *my_file, int *tb)
906 for (i=0; i<MAX_BITMAP_FILES; i++)
908 if (GameBitmaps[Textures[i].index].bm_data == bogus_data)
909 fprintf(my_file, "U");
911 fprintf(my_file, " ");
913 fprintf(my_file, "[%3i %8s] ", i, AllBitmaps[i].name);
915 fprintf(my_file, "\n");
921 // ----------------------------------------------------------------------------
922 void say_unused_walls(FILE *my_file, int *tb)
926 for (i=0; i<Num_wall_anims; i++)
928 fprintf(my_file, "Wall %3i is unused.\n", i);
931 // ----------------------------------------------------------------------------
932 static void say_totals(FILE *my_file, const char *level_name)
935 int total_robots = 0;
936 int objects_processed = 0;
938 int used_objects[MAX_OBJECTS];
940 fprintf(my_file, "\nLevel %s\n", level_name);
942 for (i=0; i<MAX_OBJECTS; i++)
945 while (objects_processed < Highest_object_index+1) {
946 int j, objtype, objid, objcount, cur_obj_val, min_obj_val, min_objnum;
948 // Find new min objnum.
949 min_obj_val = 0x7fff0000;
952 for (j=0; j<=Highest_object_index; j++) {
953 if (!used_objects[j] && Objects[j].type!=OBJ_NONE) {
954 cur_obj_val = Objects[j].type * 1000 + Objects[j].id;
955 if (cur_obj_val < min_obj_val) {
957 min_obj_val = cur_obj_val;
961 if ((min_objnum == -1) || (Objects[min_objnum].type == 255))
966 objtype = Objects[min_objnum].type;
967 objid = Objects[min_objnum].id;
969 for (i=0; i<=Highest_object_index; i++) {
970 if (!used_objects[i]) {
972 if (((Objects[i].type == objtype) && (Objects[i].id == objid)) ||
973 ((Objects[i].type == objtype) && (objtype == OBJ_PLAYER)) ||
974 ((Objects[i].type == objtype) && (objtype == OBJ_COOP)) ||
975 ((Objects[i].type == objtype) && (objtype == OBJ_HOSTAGE))) {
976 if (Objects[i].type == OBJ_ROBOT)
986 fprintf(my_file, "Object: ");
987 fprintf(my_file, "%8s %8s %3i\n", object_types(min_objnum), object_ids(min_objnum), objcount);
991 fprintf(my_file, "Total robots = %3i\n", total_robots);
994 int First_dump_level = 0;
995 int Last_dump_level = NUM_ADAM_LEVELS-1;
997 // ----------------------------------------------------------------------------
998 void say_totals_all(void)
1003 my_file = fopen( "levels.all", "wt" );
1004 // -- mprintf((1, "Fileno = %i\n", fileno(my_file)));
1007 char ErrorMessage[200];
1009 sprintf( ErrorMessage, "ERROR: Unable to open levels.all\nErrno=%i", errno );
1011 gr_palette_load(gr_palette);
1012 nm_messagebox( NULL, 1, "Ok", ErrorMessage );
1018 for (i=First_dump_level; i<=Last_dump_level; i++) {
1019 mprintf((0, "Level %i\n", i+1));
1020 load_level(Adam_level_names[i]);
1021 say_totals(my_file, Adam_level_names[i]);
1024 //--05/17/95-- for (i=0; i<NUM_SHAREWARE_LEVELS; i++) {
1025 //--05/17/95-- mprintf((0, "Level %i\n", i+1));
1026 //--05/17/95-- load_level(Shareware_level_names[i]);
1027 //--05/17/95-- say_totals(my_file, Shareware_level_names[i]);
1030 //--05/17/95-- for (i=0; i<NUM_REGISTERED_LEVELS; i++) {
1031 //--05/17/95-- mprintf((0, "Level %i\n", i+1+NUM_SHAREWARE_LEVELS));
1032 //--05/17/95-- load_level(Registered_level_names[i]);
1033 //--05/17/95-- say_totals(my_file, Registered_level_names[i]);
1040 void dump_used_textures_level(FILE *my_file, int level_num)
1043 int temp_tmap_buf[MAX_BITMAP_FILES];
1044 int perm_tmap_buf[MAX_BITMAP_FILES];
1045 sbyte level_tmap_buf[MAX_BITMAP_FILES];
1046 int temp_wall_buf[MAX_BITMAP_FILES];
1047 int perm_wall_buf[MAX_BITMAP_FILES];
1049 for (i=0; i<MAX_BITMAP_FILES; i++) {
1050 perm_tmap_buf[i] = 0;
1051 level_tmap_buf[i] = -1;
1054 for (i=0; i<MAX_BITMAP_FILES; i++) {
1055 perm_wall_buf[i] = 0;
1058 determine_used_textures_level(0, 1, level_num, temp_tmap_buf, temp_wall_buf, level_tmap_buf, MAX_BITMAP_FILES);
1059 // -- determine_used_textures_robots(temp_tmap_buf);
1060 fprintf(my_file, "\nTextures used in [%s]\n", Gamesave_current_filename);
1061 say_used_tmaps(my_file, temp_tmap_buf);
1066 // ----------------------------------------------------------------------------
1067 void dump_used_textures_all(void)
1070 int temp_tmap_buf[MAX_BITMAP_FILES];
1071 int perm_tmap_buf[MAX_BITMAP_FILES];
1072 sbyte level_tmap_buf[MAX_BITMAP_FILES];
1073 int temp_wall_buf[MAX_BITMAP_FILES];
1074 int perm_wall_buf[MAX_BITMAP_FILES];
1078 my_file = fopen( "textures.dmp", "wt" );
1079 // -- mprintf((1, "Fileno = %i\n", fileno(my_file)));
1082 char ErrorMessage[200];
1084 sprintf( ErrorMessage, "ERROR: Can't open textures.dmp\nErrno=%i", errno);
1086 gr_palette_load(gr_palette);
1087 nm_messagebox( NULL, 1, "Ok", ErrorMessage );
1093 for (i=0; i<MAX_BITMAP_FILES; i++) {
1094 perm_tmap_buf[i] = 0;
1095 level_tmap_buf[i] = -1;
1098 for (i=0; i<MAX_BITMAP_FILES; i++) {
1099 perm_wall_buf[i] = 0;
1102 // --05/17/95-- for (i=0; i<NUM_SHAREWARE_LEVELS; i++) {
1103 // --05/17/95-- determine_used_textures_level(1, 1, i, temp_tmap_buf, temp_wall_buf, level_tmap_buf, MAX_BITMAP_FILES);
1104 // --05/17/95-- fprintf(my_file, "\nTextures used in [%s]\n", Shareware_level_names[i]);
1105 // --05/17/95-- say_used_tmaps(my_file, temp_tmap_buf);
1106 // --05/17/95-- merge_buffers(perm_tmap_buf, temp_tmap_buf, MAX_BITMAP_FILES);
1107 // --05/17/95-- merge_buffers(perm_wall_buf, temp_wall_buf, MAX_BITMAP_FILES);
1110 // --05/17/95-- fprintf(my_file, "\n\nUsed textures in all shareware mines:\n");
1111 // --05/17/95-- say_used_tmaps(my_file, perm_tmap_buf);
1113 // --05/17/95-- fprintf(my_file, "\nUnused textures in all shareware mines:\n");
1114 // --05/17/95-- say_unused_tmaps(my_file, perm_tmap_buf);
1116 // --05/17/95-- fprintf(my_file, "\nTextures used exactly once in all shareware mines:\n");
1117 // --05/17/95-- say_used_once_tmaps(my_file, perm_tmap_buf, level_tmap_buf);
1119 // --05/17/95-- fprintf(my_file, "\nWall anims (eg, doors) unused in all shareware mines:\n");
1120 // --05/17/95-- say_unused_walls(my_file, perm_wall_buf);
1122 // --05/17/95-- for (i=0; i<NUM_REGISTERED_LEVELS; i++) {
1123 // --05/17/95-- determine_used_textures_level(1, 0, i, temp_tmap_buf, temp_wall_buf, level_tmap_buf, MAX_BITMAP_FILES);
1124 // --05/17/95-- fprintf(my_file, "\nTextures used in [%s]\n", Registered_level_names[i]);
1125 // --05/17/95-- say_used_tmaps(my_file, temp_tmap_buf);
1126 // --05/17/95-- merge_buffers(perm_tmap_buf, temp_tmap_buf, MAX_BITMAP_FILES);
1129 // --05/17/95-- fprintf(my_file, "\n\nUsed textures in all (including registered) mines:\n");
1130 // --05/17/95-- say_used_tmaps(my_file, perm_tmap_buf);
1132 // --05/17/95-- fprintf(my_file, "\nUnused textures in all (including registered) mines:\n");
1133 // --05/17/95-- say_unused_tmaps(my_file, perm_tmap_buf);
1135 for (i=First_dump_level; i<=Last_dump_level; i++) {
1136 determine_used_textures_level(1, 0, i, temp_tmap_buf, temp_wall_buf, level_tmap_buf, MAX_BITMAP_FILES);
1137 fprintf(my_file, "\nTextures used in [%s]\n", Adam_level_names[i]);
1138 say_used_tmaps(my_file, temp_tmap_buf);
1139 merge_buffers(perm_tmap_buf, temp_tmap_buf, MAX_BITMAP_FILES);
1142 fprintf(my_file, "\n\nUsed textures in all (including registered) mines:\n");
1143 say_used_tmaps(my_file, perm_tmap_buf);
1145 fprintf(my_file, "\nUnused textures in all (including registered) mines:\n");
1146 say_unused_tmaps(my_file, perm_tmap_buf);