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