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.
20 static char rcsid[] = "$Id: gamemine.c,v 1.9 2002-08-02 23:28:40 btb Exp $";
45 #include "editor/editor.h"
58 #define REMOVE_EXT(s) (*(strchr( (s), '.' ))='\0')
60 fix Level_shake_frequency = 0, Level_shake_duration = 0;
61 int Secret_return_segment = 0;
62 vms_matrix Secret_return_orient;
64 struct mtfi mine_top_fileinfo; // Should be same as first two fields below...
65 struct mfi mine_fileinfo;
66 struct mh mine_header;
67 struct me mine_editor;
69 typedef struct v16_segment {
71 short segnum; // segment number, not sure what it means
73 side sides[MAX_SIDES_PER_SEGMENT]; // 6 sides
74 short children[MAX_SIDES_PER_SEGMENT]; // indices of 6 children segments, front, left, top, right, bottom, back
75 short verts[MAX_VERTICES_PER_SEGMENT]; // vertex ids of 4 front and 4 back vertices
77 short group; // group number to which the segment belongs.
79 short objects; // pointer to objects in this segment
80 ubyte special; // what type of center this is
81 byte matcen_num; // which center segment is associated with.
83 fix static_light; //average static light in segment
85 short pad; //make structure longword aligned
90 ushort fileinfo_signature;
91 ushort fileinfo_version;
93 int header_offset; // Stuff common to game & editor
95 int editor_offset; // Editor specific stuff
100 int newseg_verts_offset;
101 int newseg_verts_howmany;
102 int newseg_verts_sizeof;
116 int triggers_howmany;
121 int object_offset; // Object info
124 int unused_offset; //was: doors_offset
125 int unused_howmamy; //was: doors_howmany
126 int unused_sizeof; //was: doors_sizeof
127 short level_shake_frequency, level_shake_duration; // Shakes every level_shake_frequency seconds
128 // for level_shake_duration seconds (on average, random). In 16ths second.
129 int secret_return_segment;
130 vms_matrix secret_return_orient;
132 int dl_indices_offset;
133 int dl_indices_howmany;
134 int dl_indices_sizeof;
136 int delta_light_offset;
137 int delta_light_howmany;
138 int delta_light_sizeof;
142 int CreateDefaultNewSegment();
146 static char old_tmap_list[MAX_TEXTURES][FILENAME_LEN];
147 short tmap_xlate_table[MAX_TEXTURES];
148 static short tmap_times_used[MAX_TEXTURES];
150 // -----------------------------------------------------------------------------
151 //loads from an already-open file
152 // returns 0=everything ok, 1=old version, -1=error
153 int load_mine_data(CFILE *LoadFile)
155 int i, j,oldsizeadjust;
159 int mine_start = cftell(LoadFile);
161 oldsizeadjust=(sizeof(int)*2)+sizeof (vms_matrix);
164 for (i=0; i<MAX_TEXTURES; i++ )
165 tmap_times_used[i] = 0;
168 // Create a new mine to initialize things.
169 //texpage_goto_first();
173 //===================== READ FILE INFO ========================
175 // These are the default values... version and fileinfo_sizeof
176 // don't have defaults.
177 mine_fileinfo.header_offset = -1;
178 mine_fileinfo.header_size = sizeof(mine_header);
179 mine_fileinfo.editor_offset = -1;
180 mine_fileinfo.editor_size = sizeof(mine_editor);
181 mine_fileinfo.vertex_offset = -1;
182 mine_fileinfo.vertex_howmany = 0;
183 mine_fileinfo.vertex_sizeof = sizeof(vms_vector);
184 mine_fileinfo.segment_offset = -1;
185 mine_fileinfo.segment_howmany = 0;
186 mine_fileinfo.segment_sizeof = sizeof(segment);
187 mine_fileinfo.newseg_verts_offset = -1;
188 mine_fileinfo.newseg_verts_howmany = 0;
189 mine_fileinfo.newseg_verts_sizeof = sizeof(vms_vector);
190 mine_fileinfo.group_offset = -1;
191 mine_fileinfo.group_howmany = 0;
192 mine_fileinfo.group_sizeof = sizeof(group);
193 mine_fileinfo.texture_offset = -1;
194 mine_fileinfo.texture_howmany = 0;
195 mine_fileinfo.texture_sizeof = FILENAME_LEN; // num characters in a name
196 mine_fileinfo.walls_offset = -1;
197 mine_fileinfo.walls_howmany = 0;
198 mine_fileinfo.walls_sizeof = sizeof(wall);
199 mine_fileinfo.triggers_offset = -1;
200 mine_fileinfo.triggers_howmany = 0;
201 mine_fileinfo.triggers_sizeof = sizeof(trigger);
202 mine_fileinfo.object_offset = -1;
203 mine_fileinfo.object_howmany = 1;
204 mine_fileinfo.object_sizeof = sizeof(object);
206 mine_fileinfo.level_shake_frequency = 0;
207 mine_fileinfo.level_shake_duration = 0;
209 // Delta light stuff for blowing out light sources.
210 // if (mine_top_fileinfo.fileinfo_version >= 19) {
211 mine_fileinfo.dl_indices_offset = -1;
212 mine_fileinfo.dl_indices_howmany = 0;
213 mine_fileinfo.dl_indices_sizeof = sizeof(dl_index);
215 mine_fileinfo.delta_light_offset = -1;
216 mine_fileinfo.delta_light_howmany = 0;
217 mine_fileinfo.delta_light_sizeof = sizeof(delta_light);
221 mine_fileinfo.segment2_offset = -1;
222 mine_fileinfo.segment2_howmany = 0;
223 mine_fileinfo.segment2_sizeof = sizeof(segment2);
225 // Read in mine_top_fileinfo to get size of saved fileinfo.
227 memset( &mine_top_fileinfo, 0, sizeof(mine_top_fileinfo) );
229 if (cfseek( LoadFile, mine_start, SEEK_SET ))
230 Error( "Error moving to top of file in gamemine.c" );
232 if (cfread( &mine_top_fileinfo, sizeof(mine_top_fileinfo), 1, LoadFile )!=1)
233 Error( "Error reading mine_top_fileinfo in gamemine.c" );
235 if (mine_top_fileinfo.fileinfo_signature != 0x2884)
238 // Check version number
239 if (mine_top_fileinfo.fileinfo_version < COMPATIBLE_VERSION )
242 // Now, Read in the fileinfo
243 if (cfseek( LoadFile, mine_start, SEEK_SET ))
244 Error( "Error seeking to top of file in gamemine.c" );
246 if (cfread( &mine_fileinfo, mine_top_fileinfo.fileinfo_sizeof, 1, LoadFile )!=1)
247 Error( "Error reading mine_fileinfo in gamemine.c" );
249 if (mine_top_fileinfo.fileinfo_version < 18) {
250 mprintf((1, "Old version, setting shake intensity to 0.\n"));
251 Level_shake_frequency = 0;
252 Level_shake_duration = 0;
253 Secret_return_segment = 0;
254 Secret_return_orient = vmd_identity_matrix;
256 Level_shake_frequency = mine_fileinfo.level_shake_frequency << 12;
257 Level_shake_duration = mine_fileinfo.level_shake_duration << 12;
258 Secret_return_segment = mine_fileinfo.secret_return_segment;
259 Secret_return_orient = mine_fileinfo.secret_return_orient;
262 //===================== READ HEADER INFO ========================
264 // Set default values.
265 mine_header.num_vertices = 0;
266 mine_header.num_segments = 0;
268 if (mine_fileinfo.header_offset > -1 )
270 if (cfseek( LoadFile, mine_fileinfo.header_offset, SEEK_SET ))
271 Error( "Error seeking to header_offset in gamemine.c" );
273 if (cfread( &mine_header, mine_fileinfo.header_size, 1, LoadFile )!=1)
274 Error( "Error reading mine_header in gamemine.c" );
277 //===================== READ EDITOR INFO ==========================
279 // Set default values
280 mine_editor.current_seg = 0;
281 mine_editor.newsegment_offset = -1; // To be written
282 mine_editor.newsegment_size = sizeof(segment);
283 mine_editor.Curside = 0;
284 mine_editor.Markedsegp = -1;
285 mine_editor.Markedside = 0;
287 if (mine_fileinfo.editor_offset > -1 )
289 if (cfseek( LoadFile, mine_fileinfo.editor_offset, SEEK_SET ))
290 Error( "Error seeking to editor_offset in gamemine.c" );
292 if (cfread( &mine_editor, mine_fileinfo.editor_size, 1, LoadFile )!=1)
293 Error( "Error reading mine_editor in gamemine.c" );
296 //===================== READ TEXTURE INFO ==========================
298 if ( (mine_fileinfo.texture_offset > -1) && (mine_fileinfo.texture_howmany > 0))
300 if (cfseek( LoadFile, mine_fileinfo.texture_offset, SEEK_SET ))
301 Error( "Error seeking to texture_offset in gamemine.c" );
303 for (i=0; i< mine_fileinfo.texture_howmany; i++ )
305 if (cfread( &old_tmap_list[i], mine_fileinfo.texture_sizeof, 1, LoadFile )!=1)
306 Error( "Error reading old_tmap_list[i] in gamemine.c" );
310 //=============== GENERATE TEXTURE TRANSLATION TABLE ===============
314 Assert (NumTextures < MAX_TEXTURES);
319 hashtable_init( &ht, NumTextures );
321 // Remove all the file extensions in the textures list
323 for (i=0;i<NumTextures;i++) {
324 temptr = strchr(TmapInfo[i].filename, '.');
325 if (temptr) *temptr = '\0';
326 hashtable_insert( &ht, TmapInfo[i].filename, i );
329 // For every texture, search through the texture list
330 // to find a matching name.
331 for (j=0;j<mine_fileinfo.texture_howmany;j++) {
332 // Remove this texture name's extension
333 temptr = strchr(old_tmap_list[j], '.');
334 if (temptr) *temptr = '\0';
336 tmap_xlate_table[j] = hashtable_search( &ht,old_tmap_list[j]);
337 if (tmap_xlate_table[j] < 0 ) {
338 //tmap_xlate_table[j] = 0;
339 // mprintf( (0, "Couldn't find texture '%s'\n", old_tmap_list[j] ));
342 if (tmap_xlate_table[j] != j ) translate = 1;
343 if (tmap_xlate_table[j] >= 0)
344 tmap_times_used[tmap_xlate_table[j]]++;
349 for (i=0; i<MAX_TEXTURES; i++ )
350 if (tmap_times_used[i])
352 mprintf( (0, "This mine has %d unique textures in it (~%d KB)\n", count, (count*4096) /1024 ));
355 // -- mprintf( (0, "Translate=%d\n", translate ));
357 hashtable_free( &ht );
360 //====================== READ VERTEX INFO ==========================
362 // New check added to make sure we don't read in too many vertices.
363 if ( mine_fileinfo.vertex_howmany > MAX_VERTICES )
365 mprintf((0, "Num vertices exceeds maximum. Loading MAX %d vertices\n", MAX_VERTICES));
366 mine_fileinfo.vertex_howmany = MAX_VERTICES;
369 if ( (mine_fileinfo.vertex_offset > -1) && (mine_fileinfo.vertex_howmany > 0))
371 if (cfseek( LoadFile, mine_fileinfo.vertex_offset, SEEK_SET ))
372 Error( "Error seeking to vertex_offset in gamemine.c" );
374 for (i=0; i< mine_fileinfo.vertex_howmany; i++ )
376 // Set the default values for this vertex
381 if (cfread( &Vertices[i], mine_fileinfo.vertex_sizeof, 1, LoadFile )!=1)
382 Error( "Error reading Vertices[i] in gamemine.c" );
386 //==================== READ SEGMENT INFO ===========================
388 // New check added to make sure we don't read in too many segments.
389 if ( mine_fileinfo.segment_howmany > MAX_SEGMENTS ) {
390 mprintf((0, "Num segments exceeds maximum. Loading MAX %d segments\n", MAX_SEGMENTS));
391 mine_fileinfo.segment_howmany = MAX_SEGMENTS;
392 mine_fileinfo.segment2_howmany = MAX_SEGMENTS;
395 // [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();
397 if ( (mine_fileinfo.segment_offset > -1) && (mine_fileinfo.segment_howmany > 0)) {
399 if (cfseek( LoadFile, mine_fileinfo.segment_offset,SEEK_SET ))
401 Error( "Error seeking to segment_offset in gamemine.c" );
403 Highest_segment_index = mine_fileinfo.segment_howmany-1;
405 for (i=0; i< mine_fileinfo.segment_howmany; i++ ) {
407 // Set the default values for this segment (clear to zero )
408 //memset( &Segments[i], 0, sizeof(segment) );
410 if (mine_top_fileinfo.fileinfo_version < 20) {
413 Assert(mine_fileinfo.segment_sizeof == sizeof(v16_seg));
415 if (cfread( &v16_seg, mine_fileinfo.segment_sizeof, 1, LoadFile )!=1)
416 Error( "Error reading segments in gamemine.c" );
419 Segments[i].segnum = v16_seg.segnum;
420 // -- Segments[i].pad = v16_seg.pad;
423 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
424 Segments[i].sides[j] = v16_seg.sides[j];
426 for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
427 Segments[i].children[j] = v16_seg.children[j];
429 for (j=0; j<MAX_VERTICES_PER_SEGMENT; j++)
430 Segments[i].verts[j] = v16_seg.verts[j];
432 Segment2s[i].special = v16_seg.special;
433 Segment2s[i].value = v16_seg.value;
434 Segment2s[i].s2_flags = 0;
435 Segment2s[i].matcen_num = v16_seg.matcen_num;
436 Segment2s[i].static_light = v16_seg.static_light;
437 fuelcen_activate( &Segments[i], Segment2s[i].special );
440 if (cfread( &Segments[i], mine_fileinfo.segment_sizeof, 1, LoadFile )!=1)
441 Error("Unable to read segment %i\n", i);
444 Segments[i].objects = -1;
446 Segments[i].group = -1;
449 if (mine_top_fileinfo.fileinfo_version < 15) { //used old uvl ranges
452 for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++)
453 for (uvln=0;uvln<4;uvln++) {
454 Segments[i].sides[sn].uvls[uvln].u /= 64;
455 Segments[i].sides[sn].uvls[uvln].v /= 64;
456 Segments[i].sides[sn].uvls[uvln].l /= 32;
461 for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) {
462 unsigned short orient;
463 tmap_xlate = Segments[i].sides[j].tmap_num;
464 Segments[i].sides[j].tmap_num = tmap_xlate_table[tmap_xlate];
465 if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
466 if (Segments[i].sides[j].tmap_num < 0) {
467 mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j));
469 Segments[i].sides[j].tmap_num = NumTextures-1;
471 tmap_xlate = Segments[i].sides[j].tmap_num2 & 0x3FFF;
472 orient = Segments[i].sides[j].tmap_num2 & (~0x3FFF);
473 if (tmap_xlate != 0) {
474 int xlated_tmap = tmap_xlate_table[tmap_xlate];
476 if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
477 if (xlated_tmap <= 0) {
478 mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j));
480 Segments[i].sides[j].tmap_num2 = NumTextures-1;
482 Segments[i].sides[j].tmap_num2 = xlated_tmap | orient;
488 if (mine_top_fileinfo.fileinfo_version >= 20)
489 for (i=0; i<=Highest_segment_index; i++) {
490 cfread(&Segment2s[i], sizeof(segment2), 1, LoadFile);
491 fuelcen_activate( &Segments[i], Segment2s[i].special );
495 //===================== READ NEWSEGMENT INFO =====================
499 { // Default segment created.
501 med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE)); // New_segment = Segments[0];
502 //memset( &New_segment, 0, sizeof(segment) );
505 if (mine_editor.newsegment_offset > -1)
507 if (cfseek( LoadFile, mine_editor.newsegment_offset,SEEK_SET ))
508 Error( "Error seeking to newsegment_offset in gamemine.c" );
509 if (cfread( &New_segment, mine_editor.newsegment_size,1,LoadFile )!=1)
510 Error( "Error reading new_segment in gamemine.c" );
513 if ( (mine_fileinfo.newseg_verts_offset > -1) && (mine_fileinfo.newseg_verts_howmany > 0))
515 if (cfseek( LoadFile, mine_fileinfo.newseg_verts_offset, SEEK_SET ))
516 Error( "Error seeking to newseg_verts_offset in gamemine.c" );
517 for (i=0; i< mine_fileinfo.newseg_verts_howmany; i++ )
519 // Set the default values for this vertex
520 Vertices[NEW_SEGMENT_VERTICES+i].x = 1;
521 Vertices[NEW_SEGMENT_VERTICES+i].y = 1;
522 Vertices[NEW_SEGMENT_VERTICES+i].z = 1;
524 if (cfread( &Vertices[NEW_SEGMENT_VERTICES+i], mine_fileinfo.newseg_verts_sizeof,1,LoadFile )!=1)
525 Error( "Error reading Vertices[NEW_SEGMENT_VERTICES+i] in gamemine.c" );
527 New_segment.verts[i] = NEW_SEGMENT_VERTICES+i;
533 //========================= UPDATE VARIABLES ======================
537 // Setting to Markedsegp to NULL ignores Curside and Markedside, which
538 // we want to do when reading in an old file.
540 Markedside = mine_editor.Markedside;
541 Curside = mine_editor.Curside;
543 Groupside[i] = mine_editor.Groupside[i];
545 if ( mine_editor.current_seg != -1 )
546 Cursegp = mine_editor.current_seg + Segments;
550 if (mine_editor.Markedsegp != -1 )
551 Markedsegp = mine_editor.Markedsegp + Segments;
560 Num_vertices = mine_fileinfo.vertex_howmany;
561 Num_segments = mine_fileinfo.segment_howmany;
562 Highest_vertex_index = Num_vertices-1;
563 Highest_segment_index = Num_segments-1;
565 reset_objects(1); //one object, the player
568 Highest_vertex_index = MAX_SEGMENT_VERTICES-1;
569 Highest_segment_index = MAX_SEGMENTS-1;
571 Highest_vertex_index = Num_vertices-1;
572 Highest_segment_index = Num_segments-1;
574 warn_if_concave_segments();
578 validate_segment_all();
581 //create_local_segment_data();
583 //gamemine_find_textures();
585 if (mine_top_fileinfo.fileinfo_version < MINE_VERSION )
586 return 1; //old version
593 #define COMPILED_MINE_VERSION 0
595 void read_children(int segnum,ubyte bit_mask,CFILE *LoadFile)
599 for (bit=0; bit<MAX_SIDES_PER_SEGMENT; bit++) {
600 if (bit_mask & (1 << bit)) {
601 Segments[segnum].children[bit] = cfile_read_short(LoadFile);
603 Segments[segnum].children[bit] = -1;
607 void read_verts(int segnum,CFILE *LoadFile)
610 // Read short Segments[segnum].verts[MAX_VERTICES_PER_SEGMENT]
611 for (i = 0; i < MAX_VERTICES_PER_SEGMENT; i++)
612 Segments[segnum].verts[i] = cfile_read_short(LoadFile);
615 void read_special(int segnum,ubyte bit_mask,CFILE *LoadFile)
617 if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) {
618 // Read ubyte Segment2s[segnum].special
619 Segment2s[segnum].special = cfile_read_byte(LoadFile);
620 // Read byte Segment2s[segnum].matcen_num
621 Segment2s[segnum].matcen_num = cfile_read_byte(LoadFile);
622 // Read short Segment2s[segnum].value
623 Segment2s[segnum].value = cfile_read_short(LoadFile);
625 Segment2s[segnum].special = 0;
626 Segment2s[segnum].matcen_num = -1;
627 Segment2s[segnum].value = 0;
631 int load_mine_data_compiled(CFILE *LoadFile)
633 int i, segnum, sidenum;
634 ubyte compiled_version;
639 // For compiled levels, textures map to themselves, prevent tmap_override always being gray,
640 // bug which Matt and John refused to acknowledge, so here is Mike, fixing it.
642 for (i=0; i<MAX_TEXTURES; i++)
643 tmap_xlate_table[i] = i;
646 // memset( Segments, 0, sizeof(segment)*MAX_SEGMENTS );
649 //=============================== Reading part ==============================
650 compiled_version = cfile_read_byte(LoadFile);
651 Assert( compiled_version==COMPILED_MINE_VERSION );
653 Num_vertices = cfile_read_short(LoadFile);
654 Assert( Num_vertices <= MAX_VERTICES );
656 Num_segments = cfile_read_short(LoadFile);
657 Assert( Num_segments <= MAX_SEGMENTS );
659 for (i = 0; i < Num_vertices; i++)
660 cfile_read_vector( &(Vertices[i]), LoadFile);
662 for (segnum=0; segnum<Num_segments; segnum++ ) {
665 Segments[segnum].segnum = segnum;
666 Segments[segnum].group = 0;
669 bit_mask = cfile_read_byte(LoadFile);
671 #if defined(SHAREWARE) && !defined(MACINTOSH)
672 read_special(segnum,bit_mask,LoadFile);
673 read_verts(segnum,LoadFile);
674 read_children(segnum,bit_mask,LoadFile);
676 read_children(segnum,bit_mask,LoadFile);
677 read_verts(segnum,LoadFile);
678 if (Gamesave_current_version <= 1) { // descent 1 level
679 read_special(segnum,bit_mask,LoadFile);
683 Segments[segnum].objects = -1;
686 if (Gamesave_current_version <= 1) { // descent 1 level
688 // Read fix Segments[segnum].static_light (shift down 5 bits, write as short)
689 temp_ushort = cfile_read_short(LoadFile);
690 Segment2s[segnum].static_light = ((fix)temp_ushort) << 4;
691 //cfread( &Segments[segnum].static_light, sizeof(fix), 1, LoadFile );
696 // Read the walls as a 6 byte array
697 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) {
698 Segments[segnum].sides[sidenum].pad = 0;
701 bit_mask = cfile_read_byte(LoadFile);
702 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
705 if (bit_mask & (1 << sidenum)) {
706 byte_wallnum = cfile_read_byte(LoadFile);
707 if ( byte_wallnum == 255 )
708 Segments[segnum].sides[sidenum].wall_num = -1;
710 Segments[segnum].sides[sidenum].wall_num = byte_wallnum;
712 Segments[segnum].sides[sidenum].wall_num = -1;
715 for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) {
717 if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) ) {
718 // Read short Segments[segnum].sides[sidenum].tmap_num;
719 temp_ushort = cfile_read_short(LoadFile);
720 Segments[segnum].sides[sidenum].tmap_num = temp_ushort & 0x7fff;
722 if (!(temp_ushort & 0x8000))
723 Segments[segnum].sides[sidenum].tmap_num2 = 0;
725 // Read short Segments[segnum].sides[sidenum].tmap_num2;
726 Segments[segnum].sides[sidenum].tmap_num2 = cfile_read_short(LoadFile);
729 // Read uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short)
730 for (i=0; i<4; i++ ) {
731 temp_short = cfile_read_short(LoadFile);
732 Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5;
733 temp_short = cfile_read_short(LoadFile);
734 Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5;
735 temp_ushort = cfile_read_short(LoadFile);
736 Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1;
737 //cfread( &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1, LoadFile );
740 Segments[segnum].sides[sidenum].tmap_num = 0;
741 Segments[segnum].sides[sidenum].tmap_num2 = 0;
742 for (i=0; i<4; i++ ) {
743 Segments[segnum].sides[sidenum].uvls[i].u = 0;
744 Segments[segnum].sides[sidenum].uvls[i].v = 0;
745 Segments[segnum].sides[sidenum].uvls[i].l = 0;
755 fp = fopen("segments.out", "wt");
756 for (i = 0; i <= Highest_segment_index; i++) {
757 side sides[MAX_SIDES_PER_SEGMENT]; // 6 sides
758 short children[MAX_SIDES_PER_SEGMENT]; // indices of 6 children segments, front, left, top, right, bottom, back
759 short verts[MAX_VERTICES_PER_SEGMENT]; // vertex ids of 4 front and 4 back vertices
760 int objects; // pointer to objects in this segment
762 for (j = 0; j < MAX_SIDES_PER_SEGMENT; j++) {
763 byte type; // replaces num_faces and tri_edge, 1 = quad, 2 = 0:2 triangulation, 3 = 1:3 triangulation
764 ubyte pad; //keep us longword alligned
769 vms_vector normals[2]; // 2 normals, if quadrilateral, both the same.
770 fprintf(fp, "%d\n", Segments[i].sides[j].type);
771 fprintf(fp, "%d\n", Segments[i].sides[j].pad);
772 fprintf(fp, "%d\n", Segments[i].sides[j].wall_num);
773 fprintf(fp, "%d\n", Segments[i].tmap_num);
781 Highest_vertex_index = Num_vertices-1;
782 Highest_segment_index = Num_segments-1;
784 validate_segment_all(); // Fill in side type and normals.
786 for (i=0; i<Num_segments; i++) {
788 if (Gamesave_current_version > 1)
789 segment2_read(&Segment2s[i], LoadFile);
791 fuelcen_activate( &Segments[i], Segment2s[i].special );
794 reset_objects(1); //one object, the player