]> icculus.org git repositories - btb/d2x.git/blob - main/gamemine.c
cvs2cl for building ChangeLog from RCS entries
[btb/d2x.git] / main / gamemine.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 #ifdef RCS
15 static char rcsid[] = "$Id: gamemine.c,v 1.1.1.1 2001-01-19 03:30:01 bradleyb Exp $";
16 #endif
17
18 #include <conf.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <math.h>
22 #include <string.h>
23
24 #include "pstypes.h"
25 #include "mono.h"
26
27 #include "inferno.h"
28 #include "segment.h"
29 #include "textures.h"
30 #include "wall.h"
31 #include "object.h"
32 #include "gamemine.h"
33 #include "error.h"
34 #include "gameseg.h"
35 #include "switch.h"
36
37 #include "game.h"
38 #include "newmenu.h"
39
40 #ifdef EDITOR
41 #include "editor\editor.h"
42 #endif
43
44 #include "cfile.h"              
45 #include "fuelcen.h"
46
47 #include "hash.h"
48 #include "key.h"
49 #include "piggy.h"
50
51 #include "byteswap.h"
52
53 #define REMOVE_EXT(s)  (*(strchr( (s), '.' ))='\0')
54
55 fix     Level_shake_frequency = 0, Level_shake_duration = 0;
56 int     Secret_return_segment = 0;
57 vms_matrix      Secret_return_orient;
58
59 struct mtfi mine_top_fileinfo;    // Should be same as first two fields below...
60 struct mfi mine_fileinfo;
61 struct mh mine_header;
62 struct me mine_editor;
63
64 typedef struct v16_segment {
65         #ifdef  EDITOR
66         short           segnum;                                                         // segment number, not sure what it means
67         #endif
68         side            sides[MAX_SIDES_PER_SEGMENT];   // 6 sides
69         short           children[MAX_SIDES_PER_SEGMENT];        // indices of 6 children segments, front, left, top, right, bottom, back
70         short           verts[MAX_VERTICES_PER_SEGMENT];        // vertex ids of 4 front and 4 back vertices
71         #ifdef  EDITOR
72         short           group;                                                          // group number to which the segment belongs.
73         #endif
74         short           objects;                                                                // pointer to objects in this segment
75         ubyte           special;                                                                // what type of center this is 
76         byte            matcen_num;                                                     //      which center segment is associated with.
77         short           value;
78         fix             static_light;                                           //average static light in segment
79         #ifndef EDITOR
80         short           pad;                    //make structure longword aligned
81         #endif
82 } v16_segment;
83
84 struct mfi_v19 {
85         ushort  fileinfo_signature;
86         ushort  fileinfo_version;
87         int             fileinfo_sizeof;
88         int             header_offset;          // Stuff common to game & editor
89         int             header_size;
90         int             editor_offset;   // Editor specific stuff
91         int             editor_size;
92         int             segment_offset;
93         int             segment_howmany;
94         int             segment_sizeof;
95         int             newseg_verts_offset;
96         int             newseg_verts_howmany;
97         int             newseg_verts_sizeof;
98         int             group_offset;
99         int             group_howmany;
100         int             group_sizeof;
101         int             vertex_offset;
102         int             vertex_howmany;
103         int             vertex_sizeof;
104         int             texture_offset;
105         int             texture_howmany;
106         int             texture_sizeof;
107         int             walls_offset;
108         int             walls_howmany;
109         int             walls_sizeof;
110         int             triggers_offset;
111         int             triggers_howmany;
112         int             triggers_sizeof;
113         int             links_offset;
114         int             links_howmany;
115         int             links_sizeof;
116         int             object_offset;                          // Object info
117         int             object_howmany;         
118         int             object_sizeof;  
119         int             unused_offset;                  //was: doors_offset
120         int             unused_howmamy;         //was: doors_howmany
121         int             unused_sizeof;                  //was: doors_sizeof
122         short           level_shake_frequency, level_shake_duration;    //      Shakes every level_shake_frequency seconds
123                                                                                                                                                         // for level_shake_duration seconds (on average, random).  In 16ths second.
124         int             secret_return_segment;
125         vms_matrix      secret_return_orient;
126
127         int             dl_indices_offset;
128         int             dl_indices_howmany;
129         int             dl_indices_sizeof;
130
131         int             delta_light_offset;
132         int             delta_light_howmany;
133         int             delta_light_sizeof;
134
135 };
136
137 int CreateDefaultNewSegment();
138
139 // hmm.. moved here by allender from gamesave.c -- We should really put these
140 // routines into the cfile library (i.e. cfile_read_int, etc....)
141 // This is yet another quick and dirty hack....yeech
142
143 static fix read_fix(CFILE *file)
144 {
145         fix f;
146
147         if (cfread( &f, sizeof(f), 1, file) != 1)
148                 Error( "Error reading fix in gamesave.c" );
149
150         f = (fix)INTEL_INT((int)f);
151         return f;
152 }
153
154 static void read_vector(vms_vector *v,CFILE *file)
155 {
156         v->x = read_fix(file);
157         v->y = read_fix(file);
158         v->z = read_fix(file);
159 }
160
161 static short read_short(CFILE *file)
162 {
163         short s;
164
165         if (cfread( &s, sizeof(s), 1, file) != 1)
166                 Error( "Error reading short in gamesave.c" );
167
168         s = INTEL_SHORT(s);
169         return s;
170 }
171
172 static byte read_byte(CFILE *file)
173 {
174         byte b;
175
176         if (cfread( &b, sizeof(b), 1, file) != 1)
177                 Error( "Error reading byte in gamesave.c" );
178
179         return b;
180 }
181
182 #ifdef EDITOR
183
184 static char old_tmap_list[MAX_TEXTURES][FILENAME_LEN];
185 short tmap_xlate_table[MAX_TEXTURES];
186 static short tmap_times_used[MAX_TEXTURES];
187
188 // -----------------------------------------------------------------------------
189 //loads from an already-open file
190 // returns 0=everything ok, 1=old version, -1=error
191 int load_mine_data(CFILE *LoadFile)
192 {
193         int   i, j,oldsizeadjust;
194         short tmap_xlate;
195         int     translate;
196         char    *temptr;
197         int     mine_start = cftell(LoadFile);
198
199         oldsizeadjust=(sizeof(int)*2)+sizeof (vms_matrix);
200         fuelcen_reset();
201
202         for (i=0; i<MAX_TEXTURES; i++ )
203                 tmap_times_used[i] = 0;
204         
205         #ifdef EDITOR
206         // Create a new mine to initialize things.
207         //texpage_goto_first();
208         create_new_mine();
209         #endif
210
211         //===================== READ FILE INFO ========================
212
213         // These are the default values... version and fileinfo_sizeof
214         // don't have defaults.
215         mine_fileinfo.header_offset     =   -1;
216         mine_fileinfo.header_size       =   sizeof(mine_header);
217         mine_fileinfo.editor_offset     =   -1;
218         mine_fileinfo.editor_size       =   sizeof(mine_editor);
219         mine_fileinfo.vertex_offset     =   -1;
220         mine_fileinfo.vertex_howmany    =   0;
221         mine_fileinfo.vertex_sizeof     =   sizeof(vms_vector);
222         mine_fileinfo.segment_offset    =   -1;
223         mine_fileinfo.segment_howmany   =   0;
224         mine_fileinfo.segment_sizeof    =   sizeof(segment);
225         mine_fileinfo.newseg_verts_offset     =   -1;
226         mine_fileinfo.newseg_verts_howmany    =   0;
227         mine_fileinfo.newseg_verts_sizeof     =   sizeof(vms_vector);
228         mine_fileinfo.group_offset                =     -1;
229         mine_fileinfo.group_howmany       =     0;
230         mine_fileinfo.group_sizeof                =     sizeof(group);
231         mine_fileinfo.texture_offset    =   -1;
232         mine_fileinfo.texture_howmany   =   0;
233         mine_fileinfo.texture_sizeof    =   FILENAME_LEN;  // num characters in a name
234         mine_fileinfo.walls_offset                =     -1;
235         mine_fileinfo.walls_howmany       =     0;
236         mine_fileinfo.walls_sizeof                =     sizeof(wall);  
237         mine_fileinfo.triggers_offset     =     -1;
238         mine_fileinfo.triggers_howmany  =       0;
239         mine_fileinfo.triggers_sizeof     =     sizeof(trigger);  
240         mine_fileinfo.object_offset             =       -1;
241         mine_fileinfo.object_howmany            =       1;
242         mine_fileinfo.object_sizeof             =       sizeof(object);  
243
244         mine_fileinfo.level_shake_frequency             =       0;
245         mine_fileinfo.level_shake_duration              =       0;
246
247         //      Delta light stuff for blowing out light sources.
248 //      if (mine_top_fileinfo.fileinfo_version >= 19) {
249                 mine_fileinfo.dl_indices_offset         =       -1;
250                 mine_fileinfo.dl_indices_howmany                =       0;
251                 mine_fileinfo.dl_indices_sizeof         =       sizeof(dl_index);  
252
253                 mine_fileinfo.delta_light_offset                =       -1;
254                 mine_fileinfo.delta_light_howmany               =       0;
255                 mine_fileinfo.delta_light_sizeof                =       sizeof(delta_light);  
256
257 //      }
258
259         mine_fileinfo.segment2_offset           = -1;
260         mine_fileinfo.segment2_howmany  = 0;
261         mine_fileinfo.segment2_sizeof    = sizeof(segment2);
262
263         // Read in mine_top_fileinfo to get size of saved fileinfo.
264         
265         memset( &mine_top_fileinfo, 0, sizeof(mine_top_fileinfo) );
266
267         if (cfseek( LoadFile, mine_start, SEEK_SET ))
268                 Error( "Error moving to top of file in gamemine.c" );
269
270         if (cfread( &mine_top_fileinfo, sizeof(mine_top_fileinfo), 1, LoadFile )!=1)
271                 Error( "Error reading mine_top_fileinfo in gamemine.c" );
272
273         if (mine_top_fileinfo.fileinfo_signature != 0x2884)
274                 return -1;
275
276         // Check version number
277         if (mine_top_fileinfo.fileinfo_version < COMPATIBLE_VERSION )
278                 return -1;
279
280         // Now, Read in the fileinfo
281         if (cfseek( LoadFile, mine_start, SEEK_SET ))
282                 Error( "Error seeking to top of file in gamemine.c" );
283
284         if (cfread( &mine_fileinfo, mine_top_fileinfo.fileinfo_sizeof, 1, LoadFile )!=1)
285                 Error( "Error reading mine_fileinfo in gamemine.c" );
286
287         if (mine_top_fileinfo.fileinfo_version < 18) {
288                 mprintf((1, "Old version, setting shake intensity to 0.\n"));
289                 Level_shake_frequency = 0;
290                 Level_shake_duration = 0;
291                 Secret_return_segment = 0;
292                 Secret_return_orient = vmd_identity_matrix;
293         } else {
294                 Level_shake_frequency = mine_fileinfo.level_shake_frequency << 12;
295                 Level_shake_duration = mine_fileinfo.level_shake_duration << 12;
296                 Secret_return_segment = mine_fileinfo.secret_return_segment;
297                 Secret_return_orient = mine_fileinfo.secret_return_orient;
298         }
299
300         //===================== READ HEADER INFO ========================
301
302         // Set default values.
303         mine_header.num_vertices        =   0;
304         mine_header.num_segments        =   0;
305
306         if (mine_fileinfo.header_offset > -1 )
307         {
308                 if (cfseek( LoadFile, mine_fileinfo.header_offset, SEEK_SET ))
309                         Error( "Error seeking to header_offset in gamemine.c" );
310         
311                 if (cfread( &mine_header, mine_fileinfo.header_size, 1, LoadFile )!=1)
312                         Error( "Error reading mine_header in gamemine.c" );
313         }
314
315         //===================== READ EDITOR INFO ==========================
316
317         // Set default values
318         mine_editor.current_seg         =   0;
319         mine_editor.newsegment_offset   =   -1; // To be written
320         mine_editor.newsegment_size     =   sizeof(segment);
321         mine_editor.Curside             =   0;
322         mine_editor.Markedsegp          =   -1;
323         mine_editor.Markedside          =   0;
324
325         if (mine_fileinfo.editor_offset > -1 )
326         {
327                 if (cfseek( LoadFile, mine_fileinfo.editor_offset, SEEK_SET ))
328                         Error( "Error seeking to editor_offset in gamemine.c" );
329         
330                 if (cfread( &mine_editor, mine_fileinfo.editor_size, 1, LoadFile )!=1)
331                         Error( "Error reading mine_editor in gamemine.c" );
332         }
333
334         //===================== READ TEXTURE INFO ==========================
335
336         if ( (mine_fileinfo.texture_offset > -1) && (mine_fileinfo.texture_howmany > 0))
337         {
338                 if (cfseek( LoadFile, mine_fileinfo.texture_offset, SEEK_SET ))
339                         Error( "Error seeking to texture_offset in gamemine.c" );
340
341                 for (i=0; i< mine_fileinfo.texture_howmany; i++ )
342                 {
343                         if (cfread( &old_tmap_list[i], mine_fileinfo.texture_sizeof, 1, LoadFile )!=1)
344                                 Error( "Error reading old_tmap_list[i] in gamemine.c" );
345                 }
346         }
347
348         //=============== GENERATE TEXTURE TRANSLATION TABLE ===============
349
350         translate = 0;
351         
352         Assert (NumTextures < MAX_TEXTURES);
353
354         {
355                 hashtable ht;
356         
357                 hashtable_init( &ht, NumTextures );
358         
359                 // Remove all the file extensions in the textures list
360         
361                 for (i=0;i<NumTextures;i++)     {
362                         temptr = strchr(TmapInfo[i].filename, '.');
363                         if (temptr) *temptr = '\0';
364                         hashtable_insert( &ht, TmapInfo[i].filename, i );
365                 }
366         
367                 // For every texture, search through the texture list
368                 // to find a matching name.
369                 for (j=0;j<mine_fileinfo.texture_howmany;j++)   {
370                         // Remove this texture name's extension
371                         temptr = strchr(old_tmap_list[j], '.');
372                         if (temptr) *temptr = '\0';
373         
374                         tmap_xlate_table[j] = hashtable_search( &ht,old_tmap_list[j]);
375                         if (tmap_xlate_table[j] < 0 )   {
376                                 //tmap_xlate_table[j] = 0;
377                                 // mprintf( (0, "Couldn't find texture '%s'\n", old_tmap_list[j] ));
378                                 ;
379                         }
380                         if (tmap_xlate_table[j] != j ) translate = 1;
381                         if (tmap_xlate_table[j] >= 0)
382                                 tmap_times_used[tmap_xlate_table[j]]++;
383                 }
384         
385                 {
386                         int count = 0;
387                         for (i=0; i<MAX_TEXTURES; i++ )
388                                 if (tmap_times_used[i])
389                                         count++;
390                         mprintf( (0, "This mine has %d unique textures in it (~%d KB)\n", count, (count*4096) /1024 ));
391                 }
392         
393                 // -- mprintf( (0, "Translate=%d\n", translate ));
394         
395                 hashtable_free( &ht );
396         }
397
398         //====================== READ VERTEX INFO ==========================
399
400         // New check added to make sure we don't read in too many vertices.
401         if ( mine_fileinfo.vertex_howmany > MAX_VERTICES )
402                 {
403                 mprintf((0, "Num vertices exceeds maximum.  Loading MAX %d vertices\n", MAX_VERTICES));
404                 mine_fileinfo.vertex_howmany = MAX_VERTICES;
405                 }
406
407         if ( (mine_fileinfo.vertex_offset > -1) && (mine_fileinfo.vertex_howmany > 0))
408         {
409                 if (cfseek( LoadFile, mine_fileinfo.vertex_offset, SEEK_SET ))
410                         Error( "Error seeking to vertex_offset in gamemine.c" );
411
412                 for (i=0; i< mine_fileinfo.vertex_howmany; i++ )
413                 {
414                         // Set the default values for this vertex
415                         Vertices[i].x = 1;
416                         Vertices[i].y = 1;
417                         Vertices[i].z = 1;
418
419                         if (cfread( &Vertices[i], mine_fileinfo.vertex_sizeof, 1, LoadFile )!=1)
420                                 Error( "Error reading Vertices[i] in gamemine.c" );
421                 }
422         }
423
424         //==================== READ SEGMENT INFO ===========================
425
426         // New check added to make sure we don't read in too many segments.
427         if ( mine_fileinfo.segment_howmany > MAX_SEGMENTS ) {
428                 mprintf((0, "Num segments exceeds maximum.  Loading MAX %d segments\n", MAX_SEGMENTS));
429                 mine_fileinfo.segment_howmany = MAX_SEGMENTS;
430                 mine_fileinfo.segment2_howmany = MAX_SEGMENTS;
431         }
432
433         // [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();
434
435         if ( (mine_fileinfo.segment_offset > -1) && (mine_fileinfo.segment_howmany > 0))        {
436
437                 if (cfseek( LoadFile, mine_fileinfo.segment_offset,SEEK_SET ))
438
439                         Error( "Error seeking to segment_offset in gamemine.c" );
440
441                 Highest_segment_index = mine_fileinfo.segment_howmany-1;
442
443                 for (i=0; i< mine_fileinfo.segment_howmany; i++ ) {
444
445                         // Set the default values for this segment (clear to zero )
446                         //memset( &Segments[i], 0, sizeof(segment) );
447
448                         if (mine_top_fileinfo.fileinfo_version < 20) {
449                                 v16_segment v16_seg;
450
451                                 Assert(mine_fileinfo.segment_sizeof == sizeof(v16_seg));
452
453                                 if (cfread( &v16_seg, mine_fileinfo.segment_sizeof, 1, LoadFile )!=1)
454                                         Error( "Error reading segments in gamemine.c" );
455
456                                 #ifdef EDITOR
457                                 Segments[i].segnum = v16_seg.segnum;
458                                 // -- Segments[i].pad = v16_seg.pad;
459                                 #endif
460
461                                 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
462                                         Segments[i].sides[j] = v16_seg.sides[j];
463
464                                 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
465                                         Segments[i].children[j] = v16_seg.children[j];
466
467                                 for (j=0; j<MAX_VERTICES_PER_SEGMENT; j++)
468                                         Segments[i].verts[j] = v16_seg.verts[j];
469
470                                 Segment2s[i].special = v16_seg.special;
471                                 Segment2s[i].value = v16_seg.value;
472                                 Segment2s[i].s2_flags = 0;
473                                 Segment2s[i].matcen_num = v16_seg.matcen_num;
474                                 Segment2s[i].static_light = v16_seg.static_light;
475                                 fuelcen_activate( &Segments[i], Segment2s[i].special );
476
477                         } else  {
478                                 if (cfread( &Segments[i], mine_fileinfo.segment_sizeof, 1, LoadFile )!=1)
479                                         Error("Unable to read segment %i\n", i);
480                         }
481
482                         Segments[i].objects = -1;
483                         #ifdef EDITOR
484                         Segments[i].group = -1;
485                         #endif
486
487                         if (mine_top_fileinfo.fileinfo_version < 15) {  //used old uvl ranges
488                                 int sn,uvln;
489
490                                 for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++)
491                                         for (uvln=0;uvln<4;uvln++) {
492                                                 Segments[i].sides[sn].uvls[uvln].u /= 64;
493                                                 Segments[i].sides[sn].uvls[uvln].v /= 64;
494                                                 Segments[i].sides[sn].uvls[uvln].l /= 32;
495                                         }
496                         }
497
498                         if (translate == 1)
499                                 for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) {
500                                         unsigned short orient;
501                                         tmap_xlate = Segments[i].sides[j].tmap_num;
502                                         Segments[i].sides[j].tmap_num = tmap_xlate_table[tmap_xlate];
503                                         if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
504                                                 if (Segments[i].sides[j].tmap_num < 0)  {
505                                                         mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j));
506                                                         Int3();
507                                                         Segments[i].sides[j].tmap_num = NumTextures-1;
508                                                 }
509                                         tmap_xlate = Segments[i].sides[j].tmap_num2 & 0x3FFF;
510                                         orient = Segments[i].sides[j].tmap_num2 & (~0x3FFF);
511                                         if (tmap_xlate != 0) {
512                                                 int xlated_tmap = tmap_xlate_table[tmap_xlate];
513
514                                                 if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
515                                                         if (xlated_tmap <= 0)   {
516                                                                 mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j));
517                                                                 Int3();
518                                                                 Segments[i].sides[j].tmap_num2 = NumTextures-1;
519                                                         }
520                                                 Segments[i].sides[j].tmap_num2 = xlated_tmap | orient;
521                                         }
522                                 }
523                 }
524
525
526                 if (mine_top_fileinfo.fileinfo_version >= 20)
527                         for (i=0; i<=Highest_segment_index; i++) {
528                                 cfread(&Segment2s[i], sizeof(segment2), 1, LoadFile);
529                                 fuelcen_activate( &Segments[i], Segment2s[i].special );
530                         }
531         }
532
533         //===================== READ NEWSEGMENT INFO =====================
534
535         #ifdef EDITOR
536
537         {               // Default segment created.
538                 vms_vector      sizevec;
539                 med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE));             // New_segment = Segments[0];
540                 //memset( &New_segment, 0, sizeof(segment) );
541         }
542
543         if (mine_editor.newsegment_offset > -1)
544         {
545                 if (cfseek( LoadFile, mine_editor.newsegment_offset,SEEK_SET ))
546                         Error( "Error seeking to newsegment_offset in gamemine.c" );
547                 if (cfread( &New_segment, mine_editor.newsegment_size,1,LoadFile )!=1)
548                         Error( "Error reading new_segment in gamemine.c" );
549         }
550
551         if ( (mine_fileinfo.newseg_verts_offset > -1) && (mine_fileinfo.newseg_verts_howmany > 0))
552         {
553                 if (cfseek( LoadFile, mine_fileinfo.newseg_verts_offset, SEEK_SET ))
554                         Error( "Error seeking to newseg_verts_offset in gamemine.c" );
555                 for (i=0; i< mine_fileinfo.newseg_verts_howmany; i++ )
556                 {
557                         // Set the default values for this vertex
558                         Vertices[NEW_SEGMENT_VERTICES+i].x = 1;
559                         Vertices[NEW_SEGMENT_VERTICES+i].y = 1;
560                         Vertices[NEW_SEGMENT_VERTICES+i].z = 1;
561                         
562                         if (cfread( &Vertices[NEW_SEGMENT_VERTICES+i], mine_fileinfo.newseg_verts_sizeof,1,LoadFile )!=1)
563                                 Error( "Error reading Vertices[NEW_SEGMENT_VERTICES+i] in gamemine.c" );
564
565                         New_segment.verts[i] = NEW_SEGMENT_VERTICES+i;
566                 }
567         }
568
569         #endif
570                                                                                                                         
571         //========================= UPDATE VARIABLES ======================
572
573         #ifdef EDITOR
574
575         // Setting to Markedsegp to NULL ignores Curside and Markedside, which
576         // we want to do when reading in an old file.
577         
578         Markedside = mine_editor.Markedside;
579         Curside = mine_editor.Curside;
580         for (i=0;i<10;i++)
581                 Groupside[i] = mine_editor.Groupside[i];
582
583         if ( mine_editor.current_seg != -1 )
584                 Cursegp = mine_editor.current_seg + Segments;
585         else
586                 Cursegp = NULL;
587
588         if (mine_editor.Markedsegp != -1 ) 
589                 Markedsegp = mine_editor.Markedsegp + Segments;
590         else
591                 Markedsegp = NULL;
592
593         num_groups = 0;
594         current_group = -1;
595
596         #endif
597
598         Num_vertices = mine_fileinfo.vertex_howmany;
599         Num_segments = mine_fileinfo.segment_howmany;
600         Highest_vertex_index = Num_vertices-1;
601         Highest_segment_index = Num_segments-1;
602
603         reset_objects(1);               //one object, the player
604
605         #ifdef EDITOR
606         Highest_vertex_index = MAX_SEGMENT_VERTICES-1;
607         Highest_segment_index = MAX_SEGMENTS-1;
608         set_vertex_counts();
609         Highest_vertex_index = Num_vertices-1;
610         Highest_segment_index = Num_segments-1;
611
612         warn_if_concave_segments();
613         #endif
614
615         #ifdef EDITOR
616                 validate_segment_all();
617         #endif
618
619         //create_local_segment_data();
620
621         //gamemine_find_textures();
622
623         if (mine_top_fileinfo.fileinfo_version < MINE_VERSION )
624                 return 1;               //old version
625         else
626                 return 0;
627
628 }
629 #endif
630
631 #define COMPILED_MINE_VERSION 0
632
633 void read_children(int segnum,ubyte bit_mask,CFILE *LoadFile)
634 {
635         int bit;
636
637         for (bit=0; bit<MAX_SIDES_PER_SEGMENT; bit++) {
638                 if (bit_mask & (1 << bit)) {
639                         Segments[segnum].children[bit] = read_short(LoadFile);
640 //                      cfread( &Segments[segnum].children[bit], sizeof(short), 1, LoadFile );
641                 } else
642                         Segments[segnum].children[bit] = -1;
643         }
644 }
645
646 void read_verts(int segnum,CFILE *LoadFile)
647 {
648         int i;
649         // Read short Segments[segnum].verts[MAX_VERTICES_PER_SEGMENT]
650 //      cfread( Segments[segnum].verts, sizeof(short), MAX_VERTICES_PER_SEGMENT, LoadFile );
651         for (i = 0; i < MAX_VERTICES_PER_SEGMENT; i++)
652                 Segments[segnum].verts[i] = read_short(LoadFile);
653 }
654
655 // -- void read_special(int segnum,ubyte bit_mask,CFILE *LoadFile)
656 // -- {
657 // --   if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) {
658 // --           // Read ubyte   Segments[segnum].special
659 // -- //                cfread( &Segments[segnum].special, sizeof(ubyte), 1, LoadFile );
660 // --           Segment2s[segnum].special = read_byte(LoadFile);
661 // --           // Read byte    Segments[segnum].matcen_num
662 // -- //                cfread( &Segments[segnum].matcen_num, sizeof(ubyte), 1, LoadFile );
663 // --           Segment2s[segnum].matcen_num = read_byte(LoadFile);
664 // --           // Read short   Segments[segnum].value
665 // -- //                cfread( &Segments[segnum].value, sizeof(short), 1, LoadFile );
666 // --           Segment2s[segnum].value = read_short(LoadFile);
667 // --   } else {
668 // --           Segment2s[segnum].special = 0;
669 // --           Segment2s[segnum].matcen_num = -1;
670 // --           Segment2s[segnum].value = 0;
671 // --   }
672 // -- }
673
674 int load_mine_data_compiled(CFILE *LoadFile)
675 {
676         int             i,segnum,sidenum;
677         ubyte           version;
678         short           temp_short;
679         ushort  temp_ushort;
680         ubyte           bit_mask;
681
682         //      For compiled levels, textures map to themselves, prevent tmap_override always being gray,
683         //      bug which Matt and John refused to acknowledge, so here is Mike, fixing it.
684 #ifdef EDITOR
685         for (i=0; i<MAX_TEXTURES; i++)
686                 tmap_xlate_table[i] = i;
687 #endif
688
689 //      memset( Segments, 0, sizeof(segment)*MAX_SEGMENTS );
690         fuelcen_reset();
691
692         //=============================== Reading part ==============================
693 //      cfread( &version, sizeof(ubyte), 1, LoadFile );                                         // 1 byte = compiled version
694         version = read_byte(LoadFile);
695         Assert( version==COMPILED_MINE_VERSION );
696
697 //      cfread( &temp_ushort, sizeof(ushort), 1, LoadFile );                                    // 2 bytes = Num_vertices
698 //      Num_vertices = temp_ushort;
699         Num_vertices = read_short(LoadFile);
700         Assert( Num_vertices <= MAX_VERTICES );
701
702 //      cfread( &temp_ushort, sizeof(ushort), 1, LoadFile );                                    // 2 bytes = Num_segments
703 //      Num_segments = INTEL_SHORT(temp_ushort);
704         Num_segments = read_short(LoadFile);
705         Assert( Num_segments <= MAX_SEGMENTS );
706
707 //      cfread( Vertices, sizeof(vms_vector), Num_vertices, LoadFile );
708
709         for (i = 0; i < Num_vertices; i++)
710                 read_vector( &(Vertices[i]), LoadFile);
711
712         for (segnum=0; segnum<Num_segments; segnum++ )  {
713
714                 #ifdef EDITOR
715                 Segments[segnum].segnum = segnum;
716                 Segments[segnum].group = 0;
717                 #endif
718
719                 cfread( &bit_mask, sizeof(ubyte), 1, LoadFile );
720
721                 #if defined(SHAREWARE) && !defined(MACINTOSH)
722                         // -- read_special(segnum,bit_mask,LoadFile);
723                         read_verts(segnum,LoadFile);
724                         read_children(segnum,bit_mask,LoadFile);
725                 #else
726                         read_children(segnum,bit_mask,LoadFile);
727                         read_verts(segnum,LoadFile);
728                         // --read_special(segnum,bit_mask,LoadFile);
729                 #endif
730
731                 Segments[segnum].objects = -1;
732
733                 // Read fix     Segments[segnum].static_light (shift down 5 bits, write as short)
734 //              cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile );
735 //              temp_ushort = read_short(LoadFile);
736 //              Segment2s[segnum].static_light  = ((fix)temp_ushort) << 4;
737                 //cfread( &Segments[segnum].static_light, sizeof(fix), 1, LoadFile );
738         
739                 // Read the walls as a 6 byte array
740                 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )      {
741                         Segments[segnum].sides[sidenum].pad = 0;
742                 }
743
744                 cfread( &bit_mask, sizeof(ubyte), 1, LoadFile );
745                 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
746                         ubyte byte_wallnum;
747
748                         if (bit_mask & (1 << sidenum)) {
749                                 cfread( &byte_wallnum, sizeof(ubyte), 1, LoadFile );
750                                 if ( byte_wallnum == 255 )                      
751                                         Segments[segnum].sides[sidenum].wall_num = -1;
752                                 else            
753                                         Segments[segnum].sides[sidenum].wall_num = byte_wallnum;
754                         } else
755                                         Segments[segnum].sides[sidenum].wall_num = -1;
756                 }
757
758                 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )      {
759
760                         if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) )       {
761                                 // Read short Segments[segnum].sides[sidenum].tmap_num;
762 //                              cfread( &temp_ushort, sizeof(ushort), 1, LoadFile );
763                                 temp_ushort = read_short(LoadFile);
764                                 Segments[segnum].sides[sidenum].tmap_num = temp_ushort & 0x7fff;
765
766                                 if (!(temp_ushort & 0x8000))
767                                         Segments[segnum].sides[sidenum].tmap_num2 = 0;
768                                 else {
769                                         // Read short Segments[segnum].sides[sidenum].tmap_num2;
770 //                                      cfread( &Segments[segnum].sides[sidenum].tmap_num2, sizeof(short), 1, LoadFile );
771                                         Segments[segnum].sides[sidenum].tmap_num2 = read_short(LoadFile);
772                                 }
773
774                                 // Read uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short)
775                                 for (i=0; i<4; i++ )    {
776 //                                      cfread( &temp_short, sizeof(short), 1, LoadFile );
777                                         temp_short = read_short(LoadFile);
778                                         Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5;
779 //                                      cfread( &temp_short, sizeof(short), 1, LoadFile );
780                                         temp_short = read_short(LoadFile);
781                                         Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5;
782 //                                      cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile );
783                                         temp_ushort = read_short(LoadFile);
784                                         Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1;
785                                         //cfread( &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1, LoadFile );
786                                 }       
787                         } else {
788                                 Segments[segnum].sides[sidenum].tmap_num = 0;
789                                 Segments[segnum].sides[sidenum].tmap_num2 = 0;
790                                 for (i=0; i<4; i++ )    {
791                                         Segments[segnum].sides[sidenum].uvls[i].u = 0;
792                                         Segments[segnum].sides[sidenum].uvls[i].v = 0;
793                                         Segments[segnum].sides[sidenum].uvls[i].l = 0;
794                                 }       
795                         }
796                 }
797         }
798
799 #if 0   
800         {
801                 FILE *fp;
802                 
803                 fp = fopen("segments.out", "wt");
804                 for (i = 0; i <= Highest_segment_index; i++) {
805
806         side            sides[MAX_SIDES_PER_SEGMENT];   // 6 sides
807         short           children[MAX_SIDES_PER_SEGMENT];        // indices of 6 children segments, front, left, top, right, bottom, back
808         short           verts[MAX_VERTICES_PER_SEGMENT];        // vertex ids of 4 front and 4 back vertices
809         int             objects;                                                                // pointer to objects in this segment
810
811                         for (j = 0; j < MAX_SIDES_PER_SEGMENT; j++) {
812         byte            type;                                                                   // replaces num_faces and tri_edge, 1 = quad, 2 = 0:2 triangulation, 3 = 1:3 triangulation
813         ubyte           pad;                                                                    //keep us longword alligned
814         short           wall_num;
815         short           tmap_num;
816         short           tmap_num2;
817         uvl             uvls[4];
818         vms_vector      normals[2];                                             // 2 normals, if quadrilateral, both the same.
819                                 fprintf(fp, "%d\n", Segments[i].sides[j].type;
820                                 fprintf(fp, "%d\n", Segments[i].sides[j].pad;
821                                 fprintf(fp, "%d\n", Segments[i].sides[j].wall_num;
822                                 fprintf(fp, "%d\n", Segments[i].tmap_num
823                         
824                 }
825                 fclose(fp);
826         }
827 #endif  
828
829         Highest_vertex_index = Num_vertices-1;
830         Highest_segment_index = Num_segments-1;
831
832         validate_segment_all();                 // Fill in side type and normals.
833
834 // MIKE!!!!! You should know better than this when the mac is involved!!!!!!
835
836         for (i=0; i<Num_segments; i++) {
837 // NO NO!!!!            cfread( &Segment2s[i], sizeof(segment2), 1, LoadFile );
838                 Segment2s[i].special = read_byte(LoadFile);
839                 Segment2s[i].matcen_num = read_byte(LoadFile);
840                 Segment2s[i].value = read_byte(LoadFile);
841                 Segment2s[i].s2_flags = read_byte(LoadFile);
842                 Segment2s[i].static_light = read_fix(LoadFile);
843                 fuelcen_activate( &Segments[i], Segment2s[i].special );
844         }
845
846         reset_objects(1);               //one object, the player
847
848         return 0;
849 }