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  */
convert_d1_tmap_num(short d1_tmap_num)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
load_mine_data(CFILE * LoadFile)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 
read_children(int segnum,ubyte bit_mask,CFILE * LoadFile)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 
read_verts(int segnum,CFILE * LoadFile)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 
read_special(int segnum,ubyte bit_mask,CFILE * LoadFile)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 
load_mine_data_compiled(CFILE * LoadFile)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 }
1250