This commit was manufactured by cvs2svn to create branch
[btb/d2x.git] / main / gamemine.c
1 /* $Id: gamemine.c,v 1.23 2003-04-12 02:52:38 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 for loading mines in the game
18  *
19  * Old Log:
20  * Revision 1.2  1995/10/31  10:15:58  allender
21  * code for shareware levels
22  *
23  * Revision 1.1  1995/05/16  15:25:29  allender
24  * Initial revision
25  *
26  * Revision 2.2  1995/03/06  15:23:14  john
27  * New screen techniques.
28  *
29  * Revision 2.1  1995/02/27  13:13:37  john
30  * Removed floating point.
31  *
32  * Revision 2.0  1995/02/27  11:27:45  john
33  * New version 2.0, which has no anonymous unions, builds with
34  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
35  *
36  * Revision 1.70  1995/02/13  20:35:09  john
37  * Lintized
38  *
39  * Revision 1.69  1995/02/07  17:12:03  rob
40  * Added ifdef's for Editor.
41  *
42  * Revision 1.68  1995/02/07  16:51:48  mike
43  * fix gray rock josh problem.
44  *
45  * Revision 1.67  1995/02/01  15:46:26  yuan
46  * Fixed matcen_nums.
47  *
48  * Revision 1.66  1995/01/19  15:19:28  mike
49  * new super-compressed registered file format.
50  *
51  * Revision 1.65  1994/12/10  16:44:59  matt
52  * Added debugging code to track down door that turns into rock
53  *
54  * Revision 1.64  1994/12/10  14:58:24  yuan
55  * *** empty log message ***
56  *
57  * Revision 1.63  1994/12/08  17:19:10  yuan
58  * Cfiling stuff.
59  *
60  * Revision 1.62  1994/12/07  14:05:33  yuan
61  * Fixed wall assert problem... Bashed highest_segment
62  * _index before WALL_IS_DOORWAY check.
63  *
64  * Revision 1.61  1994/11/27  23:14:52  matt
65  * Made changes for new mprintf calling convention
66  *
67  * Revision 1.60  1994/11/27  18:05:20  matt
68  * Compile out LVL reader when editor compiled out
69  *
70  * Revision 1.59  1994/11/26  22:51:45  matt
71  * Removed editor-only fields from segment structure when editor is compiled
72  * out, and padded segment structure to even multiple of 4 bytes.
73  *
74  * Revision 1.58  1994/11/26  21:48:02  matt
75  * Fixed saturation in short light value
76  *
77  * Revision 1.57  1994/11/20  22:11:49  mike
78  * comment out an apparently unnecessary call to fuelcen_reset().
79  *
80  * Revision 1.56  1994/11/18  21:56:42  john
81  * Added a better, leaner pig format.
82  *
83  * Revision 1.55  1994/11/17  20:09:18  john
84  * Added new compiled level format.
85  *
86  * Revision 1.54  1994/11/17  15:40:17  mike
87  * Comment out mprintf which was causing important information to scroll away.
88  *
89  * Revision 1.53  1994/11/17  14:56:37  mike
90  * moved segment validation functions from editor to main.
91  *
92  * Revision 1.52  1994/11/17  11:39:35  matt
93  * Ripped out code to load old mines
94  *
95  * Revision 1.51  1994/11/14  20:47:53  john
96  * Attempted to strip out all the code in the game
97  * directory that uses any ui code.
98  *
99  * Revision 1.50  1994/11/14  16:05:38  matt
100  * Fixed, maybe, again, errors when can't find texture during remap
101  *
102  * Revision 1.49  1994/11/14  14:34:03  matt
103  * Fixed up handling when textures can't be found during remap
104  *
105  * Revision 1.48  1994/11/14  13:01:55  matt
106  * Added Int3() when can't find texture
107  *
108  * Revision 1.47  1994/10/30  14:12:21  mike
109  * rip out local segments stuff.
110  *
111  * Revision 1.46  1994/10/27  19:43:07  john
112  * Disable the piglet option.
113  *
114  * Revision 1.45  1994/10/27  18:51:42  john
115  * Added -piglet option that only loads needed textures for a
116  * mine.  Only saved ~1MB, and code still doesn't free textures
117  * before you load a new mine.
118  *
119  * Revision 1.44  1994/10/20  12:47:22  matt
120  * Replace old save files (MIN/SAV/HOT) with new LVL files
121  *
122  * Revision 1.43  1994/10/19  16:46:40  matt
123  * Made tmap overrides for robots remap texture numbers
124  *
125  * Revision 1.42  1994/10/03  23:37:01  mike
126  * Adapt to changed fuelcen_activate parameters.
127  *
128  * Revision 1.41  1994/09/23  22:14:49  matt
129  * Took out obsolete structure fields
130  *
131  * Revision 1.40  1994/08/01  11:04:11  yuan
132  * New materialization centers.
133  *
134  * Revision 1.39  1994/07/21  19:01:47  mike
135  * Call Lsegment stuff.
136  *
137  *
138  */
139
140 #ifdef HAVE_CONFIG_H
141 #include <conf.h>
142 #endif
143
144 #ifdef RCS
145 static char rcsid[] = "$Id: gamemine.c,v 1.23 2003-04-12 02:52:38 btb Exp $";
146 #endif
147
148 #include <stdio.h>
149 #include <stdlib.h>
150 #include <math.h>
151 #include <string.h>
152
153 #include "pstypes.h"
154 #include "mono.h"
155
156 #include "inferno.h"
157 #include "segment.h"
158 #include "textures.h"
159 #include "wall.h"
160 #include "object.h"
161 #include "gamemine.h"
162 #include "error.h"
163 #include "gameseg.h"
164 #include "switch.h"
165
166 #include "game.h"
167 #include "newmenu.h"
168
169 #ifdef EDITOR
170 #include "editor/editor.h"
171 #endif
172
173 #include "cfile.h"
174 #include "fuelcen.h"
175
176 #include "hash.h"
177 #include "key.h"
178 #include "piggy.h"
179
180 #include "byteswap.h"
181 #include "gamesave.h"
182
183 #define REMOVE_EXT(s)  (*(strchr( (s), '.' ))='\0')
184
185 fix Level_shake_frequency = 0, Level_shake_duration = 0;
186 int Secret_return_segment = 0;
187 vms_matrix Secret_return_orient;
188
189 struct mtfi mine_top_fileinfo;    // Should be same as first two fields below...
190 struct mfi mine_fileinfo;
191 struct mh mine_header;
192 struct me mine_editor;
193
194 typedef struct v16_segment {
195         #ifdef EDITOR
196         short   segnum;             // segment number, not sure what it means
197         #endif
198         side    sides[MAX_SIDES_PER_SEGMENT];       // 6 sides
199         short   children[MAX_SIDES_PER_SEGMENT];    // indices of 6 children segments, front, left, top, right, bottom, back
200         short   verts[MAX_VERTICES_PER_SEGMENT];    // vertex ids of 4 front and 4 back vertices
201         #ifdef  EDITOR
202         short   group;              // group number to which the segment belongs.
203         #endif
204         short   objects;            // pointer to objects in this segment
205         ubyte   special;            // what type of center this is
206         byte    matcen_num;         // which center segment is associated with.
207         short   value;
208         fix     static_light;       // average static light in segment
209         #ifndef EDITOR
210         short   pad;                // make structure longword aligned
211         #endif
212 } v16_segment;
213
214 struct mfi_v19 {
215         ushort  fileinfo_signature;
216         ushort  fileinfo_version;
217         int     fileinfo_sizeof;
218         int     header_offset;      // Stuff common to game & editor
219         int     header_size;
220         int     editor_offset;      // Editor specific stuff
221         int     editor_size;
222         int     segment_offset;
223         int     segment_howmany;
224         int     segment_sizeof;
225         int     newseg_verts_offset;
226         int     newseg_verts_howmany;
227         int     newseg_verts_sizeof;
228         int     group_offset;
229         int     group_howmany;
230         int     group_sizeof;
231         int     vertex_offset;
232         int     vertex_howmany;
233         int     vertex_sizeof;
234         int     texture_offset;
235         int     texture_howmany;
236         int     texture_sizeof;
237         int     walls_offset;
238         int     walls_howmany;
239         int     walls_sizeof;
240         int     triggers_offset;
241         int     triggers_howmany;
242         int     triggers_sizeof;
243         int     links_offset;
244         int     links_howmany;
245         int     links_sizeof;
246         int     object_offset;      // Object info
247         int     object_howmany;
248         int     object_sizeof;
249         int     unused_offset;      // was: doors_offset
250         int     unused_howmamy;     // was: doors_howmany
251         int     unused_sizeof;      // was: doors_sizeof
252         short   level_shake_frequency;  // Shakes every level_shake_frequency seconds
253         short   level_shake_duration;   // for level_shake_duration seconds (on average, random).  In 16ths second.
254         int     secret_return_segment;
255         vms_matrix  secret_return_orient;
256
257         int     dl_indices_offset;
258         int     dl_indices_howmany;
259         int     dl_indices_sizeof;
260
261         int     delta_light_offset;
262         int     delta_light_howmany;
263         int     delta_light_sizeof;
264
265 };
266
267 int CreateDefaultNewSegment();
268
269 int New_file_format_load = 1; // "new file format" is everything newer than d1 shareware
270
271 int d1_pig_loaded = 0; // can descent.pig from descent 1 be loaded?
272
273 #define TMAP_NUM_MASK 0x3FFF
274
275 /* converts descent 1 texture numbers to descent 2 texture numbers
276  * textures whose names don't match between versions have extra spaces around "return"
277  * updated using the file config/convtabl.ini from the devil 2.2 level editor
278  */
279 short convert_d1_tmap_num(short d1_tmap_num) {
280         if (d1_pig_loaded && d1_tmap_num < 324) // we use original d1 textures for non-animated textures
281                 return d1_tmap_num;
282         switch (d1_tmap_num) {
283         case   0:  return  43; // grey (devil:95)
284         case   1: return 0;
285         case   2:  return  43; // grey
286         case   3: return 1;
287         case   4:  return  43; // grey
288         case   5:  return  43; // grey
289         case   6:  return  270; // blue
290         case   7:  return  271; // yellow
291         case   8: return 2;
292         case   9:  return  62; // purple (devil:179)
293         case  10:  return  272; // red
294         case  11:  return  117;
295         case  12:  return  12; //devil:43
296         case  13: return 3;
297         case  14: return 4;
298         case  15: return 5;
299         case  16: return 6;
300         case  17:  return  52;
301         case  18:  return  129;
302         case  19: return 7;
303         case  20:  return  22;
304         case  21:  return  9;
305         case  22: return 8;
306         case  23: return 9;
307         case  24: return 10;
308         case  25:  return  12; //devil:35
309         case  26: return 11;
310         case  27: return 12;
311         case  28:  return  11; //devil:43
312         case  29: return 13;
313         case  30: return 14;
314         case  31: return 15;
315         case  32: return 16;
316         case  33: return 17;
317         case  34: return 18;
318         case  35: return 19;
319         case  36: return 20;
320         case  37: return 21;
321         case  38:  return  163; //devil:27
322         case  39:  return  31; //devil:147
323         case  40: return 22;
324         case  41:  return  266;
325         case  42: return 23;
326         case  43: return 24;
327         case  44:  return  136; //devil:135
328         case  45: return 25;
329         case  46: return 26;
330         case  47: return 27;
331         case  48: return 28;
332         case  49:  return  43; //devil:60
333         case  50:  return  131; //devil:138
334         case  51: return 29;
335         case  52: return 30;
336         case  53: return 31;
337         case  54: return 32;
338         case  55:  return  165; //devil:193
339         case  56: return 33;
340         case  57:  return  132; //devil:119
341         // range handled by default case
342         case  88:  return  197; //devil:15
343         // range handled by default case
344         case 132:  return  167;
345         case 133: return 107;
346         case 134: return 108;
347         case 135: return 109;
348         case 136: return 110;
349         case 137: return 111;
350         case 138: return 112;
351         case 139: return 113;
352         case 140: return 114;
353         case 141:  return  110; //devil:106
354         case 142: return 115;
355         case 143: return 116;
356         case 144: return 117;
357         case 145: return 118;
358         case 146: return 119;
359         case 147:  return  93;
360         case 148: return 120;
361         case 149: return 121;
362         case 150: return 122;
363         case 151: return 123;
364         case 152: return 124;
365         case 153: return 125;
366         case 154:  return  27;
367         case 155:  return  126; //was: 66
368         case 156: return 200;
369         case 157: return 201;
370         case 158:  return  186; //devil:227
371         case 159:  return  190; //devil:246
372         case 160:  return  206;
373         case 161:  return  114; //devil:206
374         case 162: return 202;
375         case 163: return 203;
376         case 164: return 204;
377         case 165: return 205;
378         case 166: return 206;
379         case 167:  return  206;
380         case 168:  return  206;
381         case 169:  return  206;
382         case 170:  return  227;//206;
383         case 171:  return  206;//227;
384         case 172: return 207;
385         case 173: return 208;
386         case 174:  return  202;
387         case 175:  return  206;
388         case 176: return 209;
389         case 177: return 210;
390         case 178: return 211;
391         case 179: return 212;
392         case 180: return 213;
393         case 181: return 214;
394         case 182: return 215;
395         case 183: return 216;
396         case 184: return 217;
397         case 185:  return  217;
398         case 186: return 218;
399         case 187: return 219;
400         case 188: return 220;
401         case 189: return 221;
402         case 190: return 222;
403         case 191: return 223;
404         case 192: return 224;
405         case 193:  return  206;
406         case 194:  return  203;//206;
407         case 195:  return  234;
408         case 196: return 225;
409         case 197: return 226;
410         case 198:  return  225;
411         case 199:  return  206; //devil:204
412         case 200:  return  206; //devil:204
413         case 201: return 227;
414         case 202:  return  206; //devil:227
415         case 203: return 228;
416         case 204: return 229;
417         case 205: return 230;
418         case 206: return 231;
419         case 207: return 232;
420         case 208: return 233;
421         case 209: return 234;
422         case 210:  return  234; //devil:242
423         case 211:  return  206; //devil:240
424         case 212: return 235;
425         case 213: return 236;
426         case 214: return 237;
427         case 215: return 238;
428         case 216: return 239;
429         case 217: return 240;
430         case 218: return 241;
431         case 219: return 242;
432         case 220:  return  242; //devil:240
433         case 221: return 243;
434         case 222: return 244;
435         case 223: return  313;
436         case 224: return 245;
437         case 225: return 246;
438         case 226:  return  164;//247; matching names but not matching textures
439         case 227:  return  179; //devil:181
440         case 228:  return  196;//248; matching names but not matching textures
441         case 229:  return  15; //devil:66
442         case 230:  return  15; //devil:66
443         case 231: return 249;
444         case 232: return 250;
445         case 233: return 251;
446         case 234: return 252;
447         case 235: return 253;
448         case 236: return 254;
449         case 237: return 255;
450         case 238: return 256;
451         case 239: return 257;
452         case 240:  return  6; //devil:132
453         case 241:  return  130; //devil:131
454         case 242:  return  78; //devil:15
455         case 243:  return  33; //devil:38
456         case 244: return 258;
457         case 245: return 259;
458         case 246:  return  321;
459         case 247: return 260;
460         case 248: return 261;
461         case 249: return 262;
462         case 250:  return  340; // white entrance
463         case 251:  return  412; // red entrance
464         case 252:  return  410; // blue entrance
465         case 253:  return  411; // yellow entrance
466         case 254: return 263;
467         case 255: return 264;
468         case 256: return 265;
469         case 257:  return  249;//246;
470         case 258:  return  251;//246;
471         case 259:  return  252;//246;
472         case 260:  return  256;//246;
473         case 261: return 273;
474         case 262: return 274;
475         case 263:  return  281;
476         case 264: return 275;
477         case 265: return 276;
478         case 266:  return  279; //devil:291
479         // range handled by default case
480         case 282: return 293;
481         case 283:  return  295;
482         case 284: return 295;
483         case 285: return 296;
484         case 286: return 298;
485         // range handled by default case
486         case 298:  return  364; //devil:374
487         // range handled by default case
488         case 315:  return  361; // broken producer
489         // range handled by default case
490         case 327: return 352;
491         case 328: return 353;
492         case 329: return 354;
493         case 330:  return  380;
494         case 331:  return  379;//373; matching names but not matching textures;
495         case 332:  return  355;//344; matching names but not matching textures
496         case 333:  return  409; // lava  //devil:404
497         case 334: return 356;
498         case 335: return 357;
499         case 336: return 358;
500         case 337: return 359;
501         case 338: return 360;
502         case 339: return 361;
503         case 340: return 362;
504         case 341: return 364;
505         case 342: return 363;
506         case 343: return 366;
507         case 344: return 365;
508         case 345: return 368;
509         case 346: return 376;
510         case 347: return 370;
511         case 348: return 367;
512         case 349:  return  372;
513         case 350: return 369;
514         case 351:  return  374;//429; matching names but not matching textures
515         case 352:  return  375;//387; matching names but not matching textures
516         case 353:  return 371;
517         case 354:  return  377;//425; matching names but not matching textures
518         case 355:  return  408;
519         case 356: return 378; // lava02
520         case 357:  return  383;//384; matching names but not matching textures
521         case 358:  return  384;//385; matching names but not matching textures
522         case 359:  return  385;//386; matching names but not matching textures
523         case 360: return 386;
524         case 361: return 387;
525         case 362:  return  388; // mntr04a (devil: -1)
526         case 363: return 388;
527         case 364: return 391;
528         case 365: return 392;
529         case 366: return 393;
530         case 367: return 394;
531         case 368: return 395;
532         case 369: return 396;
533         case 370:  return  392; // mntr04b (devil: -1)
534         // range 371 - 584 handled by default
535         default:
536                 // ranges:
537                 if (d1_tmap_num >= 58 && d1_tmap_num <= 87)
538                         return d1_tmap_num - 24;
539                 if (d1_tmap_num >= 89 && d1_tmap_num <= 131)
540                         return d1_tmap_num - 25;
541                 if (d1_tmap_num >= 267 && d1_tmap_num <= 281)
542                         return d1_tmap_num + 10;
543                 if (d1_tmap_num >= 287 && d1_tmap_num <= 297)
544                         return d1_tmap_num + 13;
545                 if (d1_tmap_num >= 299 && d1_tmap_num <= 314)
546                         return d1_tmap_num + 12;
547                 if (d1_tmap_num >= 316 && d1_tmap_num <= 326)
548                         return d1_tmap_num + 11;
549                 // wall01 and door frames:
550                 if (d1_tmap_num > 370 && d1_tmap_num < 584) {
551                         if (New_file_format_load) return d1_tmap_num + 64;
552                         // d1 shareware needs special treatment:
553                         if (d1_tmap_num < 410) return d1_tmap_num + 68;
554                         if (d1_tmap_num < 417) return d1_tmap_num + 73;
555                         if (d1_tmap_num < 446) return d1_tmap_num + 91;
556                         if (d1_tmap_num < 453) return d1_tmap_num + 104;
557                         if (d1_tmap_num < 462) return d1_tmap_num + 111;
558                         if (d1_tmap_num < 486) return d1_tmap_num + 117;
559                         if (d1_tmap_num < 494) return d1_tmap_num + 141;
560                         if (d1_tmap_num < 584) return d1_tmap_num + 147;
561                 }
562                 { // handle rare case where orientation != 0
563                         short tmap_num = d1_tmap_num &  TMAP_NUM_MASK;
564                         short orient = d1_tmap_num & ~TMAP_NUM_MASK;
565                         if (orient != 0) {
566                                 return orient | convert_d1_tmap_num(tmap_num);
567                         } else {
568                                 Warning("can't convert unknown descent 1 texture #%d.\n", tmap_num);
569                                 return d1_tmap_num;
570                         }
571                 }
572         }
573 }
574
575 #ifdef EDITOR
576
577 static char old_tmap_list[MAX_TEXTURES][FILENAME_LEN];
578 short tmap_xlate_table[MAX_TEXTURES];
579 static short tmap_times_used[MAX_TEXTURES];
580
581 // -----------------------------------------------------------------------------
582 //loads from an already-open file
583 // returns 0=everything ok, 1=old version, -1=error
584 int load_mine_data(CFILE *LoadFile)
585 {
586         int   i, j,oldsizeadjust;
587         short tmap_xlate;
588         int     translate;
589         char    *temptr;
590         int     mine_start = cftell(LoadFile);
591
592         oldsizeadjust=(sizeof(int)*2)+sizeof (vms_matrix);
593         fuelcen_reset();
594
595         for (i=0; i<MAX_TEXTURES; i++ )
596                 tmap_times_used[i] = 0;
597
598         #ifdef EDITOR
599         // Create a new mine to initialize things.
600         //texpage_goto_first();
601         create_new_mine();
602         #endif
603
604         //===================== READ FILE INFO ========================
605
606         // These are the default values... version and fileinfo_sizeof
607         // don't have defaults.
608         mine_fileinfo.header_offset     =   -1;
609         mine_fileinfo.header_size       =   sizeof(mine_header);
610         mine_fileinfo.editor_offset     =   -1;
611         mine_fileinfo.editor_size       =   sizeof(mine_editor);
612         mine_fileinfo.vertex_offset     =   -1;
613         mine_fileinfo.vertex_howmany    =   0;
614         mine_fileinfo.vertex_sizeof     =   sizeof(vms_vector);
615         mine_fileinfo.segment_offset    =   -1;
616         mine_fileinfo.segment_howmany   =   0;
617         mine_fileinfo.segment_sizeof    =   sizeof(segment);
618         mine_fileinfo.newseg_verts_offset     =   -1;
619         mine_fileinfo.newseg_verts_howmany    =   0;
620         mine_fileinfo.newseg_verts_sizeof     =   sizeof(vms_vector);
621         mine_fileinfo.group_offset                =     -1;
622         mine_fileinfo.group_howmany       =     0;
623         mine_fileinfo.group_sizeof                =     sizeof(group);
624         mine_fileinfo.texture_offset    =   -1;
625         mine_fileinfo.texture_howmany   =   0;
626         mine_fileinfo.texture_sizeof    =   FILENAME_LEN;  // num characters in a name
627         mine_fileinfo.walls_offset                =     -1;
628         mine_fileinfo.walls_howmany       =     0;
629         mine_fileinfo.walls_sizeof                =     sizeof(wall);  
630         mine_fileinfo.triggers_offset     =     -1;
631         mine_fileinfo.triggers_howmany  =       0;
632         mine_fileinfo.triggers_sizeof     =     sizeof(trigger);  
633         mine_fileinfo.object_offset             =       -1;
634         mine_fileinfo.object_howmany            =       1;
635         mine_fileinfo.object_sizeof             =       sizeof(object);  
636
637         mine_fileinfo.level_shake_frequency             =       0;
638         mine_fileinfo.level_shake_duration              =       0;
639
640         //      Delta light stuff for blowing out light sources.
641 //      if (mine_top_fileinfo.fileinfo_version >= 19) {
642                 mine_fileinfo.dl_indices_offset         =       -1;
643                 mine_fileinfo.dl_indices_howmany                =       0;
644                 mine_fileinfo.dl_indices_sizeof         =       sizeof(dl_index);  
645
646                 mine_fileinfo.delta_light_offset                =       -1;
647                 mine_fileinfo.delta_light_howmany               =       0;
648                 mine_fileinfo.delta_light_sizeof                =       sizeof(delta_light);  
649
650 //      }
651
652         mine_fileinfo.segment2_offset           = -1;
653         mine_fileinfo.segment2_howmany  = 0;
654         mine_fileinfo.segment2_sizeof    = sizeof(segment2);
655
656         // Read in mine_top_fileinfo to get size of saved fileinfo.
657         
658         memset( &mine_top_fileinfo, 0, sizeof(mine_top_fileinfo) );
659
660         if (cfseek( LoadFile, mine_start, SEEK_SET ))
661                 Error( "Error moving to top of file in gamemine.c" );
662
663         if (cfread( &mine_top_fileinfo, sizeof(mine_top_fileinfo), 1, LoadFile )!=1)
664                 Error( "Error reading mine_top_fileinfo in gamemine.c" );
665
666         if (mine_top_fileinfo.fileinfo_signature != 0x2884)
667                 return -1;
668
669         // Check version number
670         if (mine_top_fileinfo.fileinfo_version < COMPATIBLE_VERSION )
671                 return -1;
672
673         // Now, Read in the fileinfo
674         if (cfseek( LoadFile, mine_start, SEEK_SET ))
675                 Error( "Error seeking to top of file in gamemine.c" );
676
677         if (cfread( &mine_fileinfo, mine_top_fileinfo.fileinfo_sizeof, 1, LoadFile )!=1)
678                 Error( "Error reading mine_fileinfo in gamemine.c" );
679
680         if (mine_top_fileinfo.fileinfo_version < 18) {
681                 mprintf((1, "Old version, setting shake intensity to 0.\n"));
682                 Level_shake_frequency = 0;
683                 Level_shake_duration = 0;
684                 Secret_return_segment = 0;
685                 Secret_return_orient = vmd_identity_matrix;
686         } else {
687                 Level_shake_frequency = mine_fileinfo.level_shake_frequency << 12;
688                 Level_shake_duration = mine_fileinfo.level_shake_duration << 12;
689                 Secret_return_segment = mine_fileinfo.secret_return_segment;
690                 Secret_return_orient = mine_fileinfo.secret_return_orient;
691         }
692
693         //===================== READ HEADER INFO ========================
694
695         // Set default values.
696         mine_header.num_vertices        =   0;
697         mine_header.num_segments        =   0;
698
699         if (mine_fileinfo.header_offset > -1 )
700         {
701                 if (cfseek( LoadFile, mine_fileinfo.header_offset, SEEK_SET ))
702                         Error( "Error seeking to header_offset in gamemine.c" );
703         
704                 if (cfread( &mine_header, mine_fileinfo.header_size, 1, LoadFile )!=1)
705                         Error( "Error reading mine_header in gamemine.c" );
706         }
707
708         //===================== READ EDITOR INFO ==========================
709
710         // Set default values
711         mine_editor.current_seg         =   0;
712         mine_editor.newsegment_offset   =   -1; // To be written
713         mine_editor.newsegment_size     =   sizeof(segment);
714         mine_editor.Curside             =   0;
715         mine_editor.Markedsegp          =   -1;
716         mine_editor.Markedside          =   0;
717
718         if (mine_fileinfo.editor_offset > -1 )
719         {
720                 if (cfseek( LoadFile, mine_fileinfo.editor_offset, SEEK_SET ))
721                         Error( "Error seeking to editor_offset in gamemine.c" );
722         
723                 if (cfread( &mine_editor, mine_fileinfo.editor_size, 1, LoadFile )!=1)
724                         Error( "Error reading mine_editor in gamemine.c" );
725         }
726
727         //===================== READ TEXTURE INFO ==========================
728
729         if ( (mine_fileinfo.texture_offset > -1) && (mine_fileinfo.texture_howmany > 0))
730         {
731                 if (cfseek( LoadFile, mine_fileinfo.texture_offset, SEEK_SET ))
732                         Error( "Error seeking to texture_offset in gamemine.c" );
733
734                 for (i=0; i< mine_fileinfo.texture_howmany; i++ )
735                 {
736                         if (cfread( &old_tmap_list[i], mine_fileinfo.texture_sizeof, 1, LoadFile )!=1)
737                                 Error( "Error reading old_tmap_list[i] in gamemine.c" );
738                 }
739         }
740
741         //=============== GENERATE TEXTURE TRANSLATION TABLE ===============
742
743         translate = 0;
744         
745         Assert (NumTextures < MAX_TEXTURES);
746
747         {
748                 hashtable ht;
749         
750                 hashtable_init( &ht, NumTextures );
751         
752                 // Remove all the file extensions in the textures list
753         
754                 for (i=0;i<NumTextures;i++)     {
755                         temptr = strchr(TmapInfo[i].filename, '.');
756                         if (temptr) *temptr = '\0';
757                         hashtable_insert( &ht, TmapInfo[i].filename, i );
758                 }
759         
760                 // For every texture, search through the texture list
761                 // to find a matching name.
762                 for (j=0;j<mine_fileinfo.texture_howmany;j++)   {
763                         // Remove this texture name's extension
764                         temptr = strchr(old_tmap_list[j], '.');
765                         if (temptr) *temptr = '\0';
766         
767                         tmap_xlate_table[j] = hashtable_search( &ht,old_tmap_list[j]);
768                         if (tmap_xlate_table[j] < 0 )   {
769                                 //tmap_xlate_table[j] = 0;
770                                 // mprintf( (0, "Couldn't find texture '%s'\n", old_tmap_list[j] ));
771                                 ;
772                         }
773                         if (tmap_xlate_table[j] != j ) translate = 1;
774                         if (tmap_xlate_table[j] >= 0)
775                                 tmap_times_used[tmap_xlate_table[j]]++;
776                 }
777         
778                 {
779                         int count = 0;
780                         for (i=0; i<MAX_TEXTURES; i++ )
781                                 if (tmap_times_used[i])
782                                         count++;
783                         mprintf( (0, "This mine has %d unique textures in it (~%d KB)\n", count, (count*4096) /1024 ));
784                 }
785         
786                 // -- mprintf( (0, "Translate=%d\n", translate ));
787         
788                 hashtable_free( &ht );
789         }
790
791         //====================== READ VERTEX INFO ==========================
792
793         // New check added to make sure we don't read in too many vertices.
794         if ( mine_fileinfo.vertex_howmany > MAX_VERTICES )
795                 {
796                 mprintf((0, "Num vertices exceeds maximum.  Loading MAX %d vertices\n", MAX_VERTICES));
797                 mine_fileinfo.vertex_howmany = MAX_VERTICES;
798                 }
799
800         if ( (mine_fileinfo.vertex_offset > -1) && (mine_fileinfo.vertex_howmany > 0))
801         {
802                 if (cfseek( LoadFile, mine_fileinfo.vertex_offset, SEEK_SET ))
803                         Error( "Error seeking to vertex_offset in gamemine.c" );
804
805                 for (i=0; i< mine_fileinfo.vertex_howmany; i++ )
806                 {
807                         // Set the default values for this vertex
808                         Vertices[i].x = 1;
809                         Vertices[i].y = 1;
810                         Vertices[i].z = 1;
811
812                         if (cfread( &Vertices[i], mine_fileinfo.vertex_sizeof, 1, LoadFile )!=1)
813                                 Error( "Error reading Vertices[i] in gamemine.c" );
814                 }
815         }
816
817         //==================== READ SEGMENT INFO ===========================
818
819         // New check added to make sure we don't read in too many segments.
820         if ( mine_fileinfo.segment_howmany > MAX_SEGMENTS ) {
821                 mprintf((0, "Num segments exceeds maximum.  Loading MAX %d segments\n", MAX_SEGMENTS));
822                 mine_fileinfo.segment_howmany = MAX_SEGMENTS;
823                 mine_fileinfo.segment2_howmany = MAX_SEGMENTS;
824         }
825
826         // [commented out by mk on 11/20/94 (weren't we supposed to hit final in October?) because it looks redundant.  I think I'll test it now...]  fuelcen_reset();
827
828         if ( (mine_fileinfo.segment_offset > -1) && (mine_fileinfo.segment_howmany > 0))        {
829
830                 if (cfseek( LoadFile, mine_fileinfo.segment_offset,SEEK_SET ))
831
832                         Error( "Error seeking to segment_offset in gamemine.c" );
833
834                 Highest_segment_index = mine_fileinfo.segment_howmany-1;
835
836                 for (i=0; i< mine_fileinfo.segment_howmany; i++ ) {
837
838                         // Set the default values for this segment (clear to zero )
839                         //memset( &Segments[i], 0, sizeof(segment) );
840
841                         if (mine_top_fileinfo.fileinfo_version < 20) {
842                                 v16_segment v16_seg;
843
844                                 Assert(mine_fileinfo.segment_sizeof == sizeof(v16_seg));
845
846                                 if (cfread( &v16_seg, mine_fileinfo.segment_sizeof, 1, LoadFile )!=1)
847                                         Error( "Error reading segments in gamemine.c" );
848
849                                 #ifdef EDITOR
850                                 Segments[i].segnum = v16_seg.segnum;
851                                 // -- Segments[i].pad = v16_seg.pad;
852                                 #endif
853
854                                 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
855                                         Segments[i].sides[j] = v16_seg.sides[j];
856
857                                 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
858                                         Segments[i].children[j] = v16_seg.children[j];
859
860                                 for (j=0; j<MAX_VERTICES_PER_SEGMENT; j++)
861                                         Segments[i].verts[j] = v16_seg.verts[j];
862
863                                 Segment2s[i].special = v16_seg.special;
864                                 Segment2s[i].value = v16_seg.value;
865                                 Segment2s[i].s2_flags = 0;
866                                 Segment2s[i].matcen_num = v16_seg.matcen_num;
867                                 Segment2s[i].static_light = v16_seg.static_light;
868                                 fuelcen_activate( &Segments[i], Segment2s[i].special );
869
870                         } else  {
871                                 if (cfread( &Segments[i], mine_fileinfo.segment_sizeof, 1, LoadFile )!=1)
872                                         Error("Unable to read segment %i\n", i);
873                         }
874
875                         Segments[i].objects = -1;
876                         #ifdef EDITOR
877                         Segments[i].group = -1;
878                         #endif
879
880                         if (mine_top_fileinfo.fileinfo_version < 15) {  //used old uvl ranges
881                                 int sn,uvln;
882
883                                 for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++)
884                                         for (uvln=0;uvln<4;uvln++) {
885                                                 Segments[i].sides[sn].uvls[uvln].u /= 64;
886                                                 Segments[i].sides[sn].uvls[uvln].v /= 64;
887                                                 Segments[i].sides[sn].uvls[uvln].l /= 32;
888                                         }
889                         }
890
891                         if (translate == 1)
892                                 for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) {
893                                         unsigned short orient;
894                                         tmap_xlate = Segments[i].sides[j].tmap_num;
895                                         Segments[i].sides[j].tmap_num = tmap_xlate_table[tmap_xlate];
896                                         if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
897                                                 if (Segments[i].sides[j].tmap_num < 0)  {
898                                                         mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j));
899                                                         Int3();
900                                                         Segments[i].sides[j].tmap_num = NumTextures-1;
901                                                 }
902                                         tmap_xlate = Segments[i].sides[j].tmap_num2 & TMAP_NUM_MASK;
903                                         orient = Segments[i].sides[j].tmap_num2 & (~TMAP_NUM_MASK);
904                                         if (tmap_xlate != 0) {
905                                                 int xlated_tmap = tmap_xlate_table[tmap_xlate];
906
907                                                 if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
908                                                         if (xlated_tmap <= 0)   {
909                                                                 mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j));
910                                                                 Int3();
911                                                                 Segments[i].sides[j].tmap_num2 = NumTextures-1;
912                                                         }
913                                                 Segments[i].sides[j].tmap_num2 = xlated_tmap | orient;
914                                         }
915                                 }
916                 }
917
918
919                 if (mine_top_fileinfo.fileinfo_version >= 20)
920                         for (i=0; i<=Highest_segment_index; i++) {
921                                 cfread(&Segment2s[i], sizeof(segment2), 1, LoadFile);
922                                 fuelcen_activate( &Segments[i], Segment2s[i].special );
923                         }
924         }
925
926         //===================== READ NEWSEGMENT INFO =====================
927
928         #ifdef EDITOR
929
930         {               // Default segment created.
931                 vms_vector      sizevec;
932                 med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE));             // New_segment = Segments[0];
933                 //memset( &New_segment, 0, sizeof(segment) );
934         }
935
936         if (mine_editor.newsegment_offset > -1)
937         {
938                 if (cfseek( LoadFile, mine_editor.newsegment_offset,SEEK_SET ))
939                         Error( "Error seeking to newsegment_offset in gamemine.c" );
940                 if (cfread( &New_segment, mine_editor.newsegment_size,1,LoadFile )!=1)
941                         Error( "Error reading new_segment in gamemine.c" );
942         }
943
944         if ( (mine_fileinfo.newseg_verts_offset > -1) && (mine_fileinfo.newseg_verts_howmany > 0))
945         {
946                 if (cfseek( LoadFile, mine_fileinfo.newseg_verts_offset, SEEK_SET ))
947                         Error( "Error seeking to newseg_verts_offset in gamemine.c" );
948                 for (i=0; i< mine_fileinfo.newseg_verts_howmany; i++ )
949                 {
950                         // Set the default values for this vertex
951                         Vertices[NEW_SEGMENT_VERTICES+i].x = 1;
952                         Vertices[NEW_SEGMENT_VERTICES+i].y = 1;
953                         Vertices[NEW_SEGMENT_VERTICES+i].z = 1;
954                         
955                         if (cfread( &Vertices[NEW_SEGMENT_VERTICES+i], mine_fileinfo.newseg_verts_sizeof,1,LoadFile )!=1)
956                                 Error( "Error reading Vertices[NEW_SEGMENT_VERTICES+i] in gamemine.c" );
957
958                         New_segment.verts[i] = NEW_SEGMENT_VERTICES+i;
959                 }
960         }
961
962         #endif
963                                                                                                                         
964         //========================= UPDATE VARIABLES ======================
965
966         #ifdef EDITOR
967
968         // Setting to Markedsegp to NULL ignores Curside and Markedside, which
969         // we want to do when reading in an old file.
970         
971         Markedside = mine_editor.Markedside;
972         Curside = mine_editor.Curside;
973         for (i=0;i<10;i++)
974                 Groupside[i] = mine_editor.Groupside[i];
975
976         if ( mine_editor.current_seg != -1 )
977                 Cursegp = mine_editor.current_seg + Segments;
978         else
979                 Cursegp = NULL;
980
981         if (mine_editor.Markedsegp != -1 ) 
982                 Markedsegp = mine_editor.Markedsegp + Segments;
983         else
984                 Markedsegp = NULL;
985
986         num_groups = 0;
987         current_group = -1;
988
989         #endif
990
991         Num_vertices = mine_fileinfo.vertex_howmany;
992         Num_segments = mine_fileinfo.segment_howmany;
993         Highest_vertex_index = Num_vertices-1;
994         Highest_segment_index = Num_segments-1;
995
996         reset_objects(1);               //one object, the player
997
998         #ifdef EDITOR
999         Highest_vertex_index = MAX_SEGMENT_VERTICES-1;
1000         Highest_segment_index = MAX_SEGMENTS-1;
1001         set_vertex_counts();
1002         Highest_vertex_index = Num_vertices-1;
1003         Highest_segment_index = Num_segments-1;
1004
1005         warn_if_concave_segments();
1006         #endif
1007
1008         #ifdef EDITOR
1009                 validate_segment_all();
1010         #endif
1011
1012         //create_local_segment_data();
1013
1014         //gamemine_find_textures();
1015
1016         if (mine_top_fileinfo.fileinfo_version < MINE_VERSION )
1017                 return 1;               //old version
1018         else
1019                 return 0;
1020
1021 }
1022 #endif
1023
1024 #define COMPILED_MINE_VERSION 0
1025
1026 void read_children(int segnum,ubyte bit_mask,CFILE *LoadFile)
1027 {
1028         int bit;
1029
1030         for (bit=0; bit<MAX_SIDES_PER_SEGMENT; bit++) {
1031                 if (bit_mask & (1 << bit)) {
1032                         Segments[segnum].children[bit] = cfile_read_short(LoadFile);
1033                 } else
1034                         Segments[segnum].children[bit] = -1;
1035         }
1036 }
1037
1038 void read_verts(int segnum,CFILE *LoadFile)
1039 {
1040         int i;
1041         // Read short Segments[segnum].verts[MAX_VERTICES_PER_SEGMENT]
1042         for (i = 0; i < MAX_VERTICES_PER_SEGMENT; i++)
1043                 Segments[segnum].verts[i] = cfile_read_short(LoadFile);
1044 }
1045
1046 void read_special(int segnum,ubyte bit_mask,CFILE *LoadFile)
1047 {
1048         if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) {
1049                 // Read ubyte   Segment2s[segnum].special
1050                 Segment2s[segnum].special = cfile_read_byte(LoadFile);
1051                 // Read byte    Segment2s[segnum].matcen_num
1052                 Segment2s[segnum].matcen_num = cfile_read_byte(LoadFile);
1053                 // Read short   Segment2s[segnum].value
1054                 Segment2s[segnum].value = cfile_read_short(LoadFile);
1055         } else {
1056                 Segment2s[segnum].special = 0;
1057                 Segment2s[segnum].matcen_num = -1;
1058                 Segment2s[segnum].value = 0;
1059         }
1060 }
1061
1062 int load_mine_data_compiled(CFILE *LoadFile)
1063 {
1064         int     i, segnum, sidenum;
1065         ubyte   compiled_version;
1066         short   temp_short;
1067         ushort  temp_ushort = 0;
1068         ubyte   bit_mask;
1069
1070         if (!strcmp(strchr(Gamesave_current_filename, '.'), ".sdl"))
1071                 New_file_format_load = 0; // descent 1 shareware
1072         else
1073                 New_file_format_load = 1;
1074
1075         //      For compiled levels, textures map to themselves, prevent tmap_override always being gray,
1076         //      bug which Matt and John refused to acknowledge, so here is Mike, fixing it.
1077 #ifdef EDITOR
1078         for (i=0; i<MAX_TEXTURES; i++)
1079                 tmap_xlate_table[i] = i;
1080 #endif
1081
1082 //      memset( Segments, 0, sizeof(segment)*MAX_SEGMENTS );
1083         fuelcen_reset();
1084
1085         //=============================== Reading part ==============================
1086         compiled_version = cfile_read_byte(LoadFile);
1087         //Assert( compiled_version==COMPILED_MINE_VERSION );
1088         if (compiled_version!=COMPILED_MINE_VERSION)
1089                 mprintf((0,"compiled mine version=%i\n", compiled_version)); //many levels have "wrong" versions.  Theres no point in aborting because of it, I think.
1090
1091         if (New_file_format_load)
1092                 Num_vertices = cfile_read_short(LoadFile);
1093         else
1094                 Num_vertices = cfile_read_int(LoadFile);
1095         Assert( Num_vertices <= MAX_VERTICES );
1096
1097         if (New_file_format_load)
1098                 Num_segments = cfile_read_short(LoadFile);
1099         else
1100                 Num_segments = cfile_read_int(LoadFile);
1101         Assert( Num_segments <= MAX_SEGMENTS );
1102
1103         for (i = 0; i < Num_vertices; i++)
1104                 cfile_read_vector( &(Vertices[i]), LoadFile);
1105
1106         for (segnum=0; segnum<Num_segments; segnum++ )  {
1107
1108                 #ifdef EDITOR
1109                 Segments[segnum].segnum = segnum;
1110                 Segments[segnum].group = 0;
1111                 #endif
1112
1113                 if (New_file_format_load)
1114                         bit_mask = cfile_read_byte(LoadFile);
1115                 else
1116                         bit_mask = 0x7f; // read all six children and special stuff...
1117
1118                 if (Gamesave_current_version == 5) { // d2 SHAREWARE level
1119                         read_special(segnum,bit_mask,LoadFile);
1120                         read_verts(segnum,LoadFile);
1121                         read_children(segnum,bit_mask,LoadFile);
1122                 } else {
1123                         read_children(segnum,bit_mask,LoadFile);
1124                         read_verts(segnum,LoadFile);
1125                         if (Gamesave_current_version <= 1) { // descent 1 level
1126                                 read_special(segnum,bit_mask,LoadFile);
1127                         }
1128                 }
1129
1130                 Segments[segnum].objects = -1;
1131
1132                 if (Gamesave_current_version <= 5) { // descent 1 thru d2 SHAREWARE level
1133                         // Read fix     Segments[segnum].static_light (shift down 5 bits, write as short)
1134                         temp_ushort = cfile_read_short(LoadFile);
1135                         Segment2s[segnum].static_light  = ((fix)temp_ushort) << 4;
1136                         //cfread( &Segments[segnum].static_light, sizeof(fix), 1, LoadFile );
1137                 }
1138
1139                 // Read the walls as a 6 byte array
1140                 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )      {
1141                         Segments[segnum].sides[sidenum].pad = 0;
1142                 }
1143
1144                 if (New_file_format_load)
1145                         bit_mask = cfile_read_byte(LoadFile);
1146                 else
1147                         bit_mask = 0x3f; // read all six sides
1148                 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
1149                         ubyte byte_wallnum;
1150
1151                         if (bit_mask & (1 << sidenum)) {
1152                                 byte_wallnum = cfile_read_byte(LoadFile);
1153                                 if ( byte_wallnum == 255 )
1154                                         Segments[segnum].sides[sidenum].wall_num = -1;
1155                                 else
1156                                         Segments[segnum].sides[sidenum].wall_num = byte_wallnum;
1157                         } else
1158                                         Segments[segnum].sides[sidenum].wall_num = -1;
1159                 }
1160
1161                 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )      {
1162
1163                         if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) )       {
1164                                 // Read short Segments[segnum].sides[sidenum].tmap_num;
1165                                 if (New_file_format_load) {
1166                                         temp_ushort = cfile_read_short(LoadFile);
1167                                         Segments[segnum].sides[sidenum].tmap_num = temp_ushort & 0x7fff;
1168                                 } else
1169                                         Segments[segnum].sides[sidenum].tmap_num = cfile_read_short(LoadFile);
1170
1171                                 if (Gamesave_current_version <= 1)
1172                                         Segments[segnum].sides[sidenum].tmap_num = convert_d1_tmap_num(Segments[segnum].sides[sidenum].tmap_num);
1173
1174                                 if (New_file_format_load && !(temp_ushort & 0x8000))
1175                                         Segments[segnum].sides[sidenum].tmap_num2 = 0;
1176                                 else {
1177                                         // Read short Segments[segnum].sides[sidenum].tmap_num2;
1178                                         Segments[segnum].sides[sidenum].tmap_num2 = cfile_read_short(LoadFile);
1179                                         if (Gamesave_current_version <= 1 && Segments[segnum].sides[sidenum].tmap_num2 != 0)
1180                                                 Segments[segnum].sides[sidenum].tmap_num2 = convert_d1_tmap_num(Segments[segnum].sides[sidenum].tmap_num2);
1181                                 }
1182
1183                                 // Read uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short)
1184                                 for (i=0; i<4; i++ )    {
1185                                         temp_short = cfile_read_short(LoadFile);
1186                                         Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5;
1187                                         temp_short = cfile_read_short(LoadFile);
1188                                         Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5;
1189                                         temp_ushort = cfile_read_short(LoadFile);
1190                                         Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1;
1191                                         //cfread( &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1, LoadFile );
1192                                 }
1193                         } else {
1194                                 Segments[segnum].sides[sidenum].tmap_num = 0;
1195                                 Segments[segnum].sides[sidenum].tmap_num2 = 0;
1196                                 for (i=0; i<4; i++ )    {
1197                                         Segments[segnum].sides[sidenum].uvls[i].u = 0;
1198                                         Segments[segnum].sides[sidenum].uvls[i].v = 0;
1199                                         Segments[segnum].sides[sidenum].uvls[i].l = 0;
1200                                 }
1201                         }
1202                 }
1203         }
1204
1205 #if 0
1206         {
1207                 FILE *fp;
1208
1209                 fp = fopen("segments.out", "wt");
1210                 for (i = 0; i <= Highest_segment_index; i++) {
1211                         side    sides[MAX_SIDES_PER_SEGMENT];   // 6 sides
1212                         short   children[MAX_SIDES_PER_SEGMENT];        // indices of 6 children segments, front, left, top, right, bottom, back
1213                         short   verts[MAX_VERTICES_PER_SEGMENT];        // vertex ids of 4 front and 4 back vertices
1214                         int             objects;                                                                // pointer to objects in this segment
1215
1216                         for (j = 0; j < MAX_SIDES_PER_SEGMENT; j++) {
1217                                 byte    type;                                                                   // replaces num_faces and tri_edge, 1 = quad, 2 = 0:2 triangulation, 3 = 1:3 triangulation
1218                                 ubyte   pad;                                                                    //keep us longword alligned
1219                                 short   wall_num;
1220                                 short   tmap_num;
1221                                 short   tmap_num2;
1222                                 uvl             uvls[4];
1223                                 vms_vector      normals[2];                                             // 2 normals, if quadrilateral, both the same.
1224                                 fprintf(fp, "%d\n", Segments[i].sides[j].type);
1225                                 fprintf(fp, "%d\n", Segments[i].sides[j].pad);
1226                                 fprintf(fp, "%d\n", Segments[i].sides[j].wall_num);
1227                                 fprintf(fp, "%d\n", Segments[i].tmap_num);
1228
1229                         }
1230                         fclose(fp);
1231                 }
1232         }
1233 #endif
1234
1235         Highest_vertex_index = Num_vertices-1;
1236         Highest_segment_index = Num_segments-1;
1237
1238         validate_segment_all();                 // Fill in side type and normals.
1239
1240         for (i=0; i<Num_segments; i++) {
1241                 if (Gamesave_current_version > 5)
1242                         segment2_read(&Segment2s[i], LoadFile);
1243                 fuelcen_activate( &Segments[i], Segment2s[i].special );
1244         }
1245
1246         reset_objects(1);               //one object, the player
1247
1248         return 0;
1249 }