home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / editor / mine.c < prev    next >
C/C++ Source or Header  |  1998-06-08  |  19KB  |  543 lines

  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-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: f:/miner/source/main/editor/rcs/mine.c $
  15.  * $Revision: 2.0 $
  16.  * $Author: john $
  17.  * $Date: 1995/02/27 11:34:38 $
  18.  * 
  19.  * Mine specific editing functions, such as load_mine, save_mine
  20.  * 
  21.  * $Log: mine.c $
  22.  * Revision 2.0  1995/02/27  11:34:38  john
  23.  * Version 2.0! No anonymous unions, Watcom 10.0, with no need
  24.  * for bitmaps.tbl.
  25.  * 
  26.  * Revision 1.82  1995/01/19  15:19:42  mike
  27.  * New super-compressed registered file format.
  28.  * 
  29.  * Revision 1.81  1994/12/15  16:51:39  mike
  30.  * fix error message.
  31.  * 
  32.  * Revision 1.80  1994/12/09  22:52:27  yuan
  33.  * *** empty log message ***
  34.  * 
  35.  * Revision 1.79  1994/11/27  23:17:14  matt
  36.  * Made changes for new mprintf calling convention
  37.  * 
  38.  * Revision 1.78  1994/11/26  21:48:24  matt
  39.  * Fixed saturation in short light value
  40.  * 
  41.  * Revision 1.77  1994/11/18  09:43:22  mike
  42.  * mprintf and clean up instead of Assert on values which don't fit in a short.
  43.  * 
  44.  * Revision 1.76  1994/11/17  20:37:37  john
  45.  * Added comment to get mike or john.
  46.  * 
  47.  * Revision 1.75  1994/11/17  20:08:51  john
  48.  * Added new compiled level format.
  49.  * 
  50.  * Revision 1.74  1994/11/17  11:39:00  matt
  51.  * Ripped out code to load old mines
  52.  * 
  53.  * Revision 1.73  1994/10/20  12:47:47  matt
  54.  * Replaced old save files (MIN/SAV/HOT) with new LVL files
  55.  * 
  56.  * Revision 1.72  1994/09/23  22:13:58  matt
  57.  * Tooks out references to obsolete structure fields
  58.  * 
  59.  * Revision 1.71  1994/09/22  18:39:40  john
  60.  * *** empty log message ***
  61.  * 
  62.  * Revision 1.70  1994/09/22  18:38:09  john
  63.  * Added better help for locked files.
  64.  * 
  65.  * Revision 1.69  1994/08/01  11:04:44  yuan
  66.  * New materialization centers.
  67.  * 
  68.  * Revision 1.68  1994/06/08  14:29:35  matt
  69.  * Took out support for old mine versions
  70.  * 
  71.  * Revision 1.67  1994/05/27  10:34:37  yuan
  72.  * Added new Dialog boxes for Walls and Triggers.
  73.  * 
  74.  * Revision 1.66  1994/05/23  14:48:08  mike
  75.  * make current segment be add segment.
  76.  * 
  77.  * Revision 1.65  1994/05/17  10:34:52  matt
  78.  * New parm to reset_objects; Num_objects no longer global
  79.  * 
  80.  * Revision 1.64  1994/05/12  14:46:46  mike
  81.  * Load previous mine type.
  82.  * 
  83.  * Revision 1.63  1994/05/06  12:52:13  yuan
  84.  * Adding some gamesave checks...
  85.  * 
  86.  * Revision 1.62  1994/05/05  12:56:32  yuan
  87.  * Fixed a bunch of group bugs.
  88.  * 
  89.  * Revision 1.61  1994/05/03  11:36:55  yuan
  90.  * Fixing mine save.
  91.  * 
  92.  * Revision 1.60  1994/03/19  17:22:14  yuan
  93.  * Wall system implemented until specific features need to be added...
  94.  * (Needs to be hammered on though.)
  95.  * 
  96.  * Revision 1.59  1994/03/17  18:08:32  yuan
  97.  * New wall stuff... Cut out switches....
  98.  * 
  99.  * Revision 1.58  1994/03/15  16:34:15  yuan
  100.  * Fixed bm loader (might have some changes in walls and switches)
  101.  * 
  102.  * Revision 1.57  1994/03/01  18:14:09  yuan
  103.  * Added new walls, switches, and triggers.
  104.  * 
  105.  */
  106.  
  107.  
  108. #pragma off (unreferenced)
  109. static char rcsid[] = "$Id: mine.c 2.0 1995/02/27 11:34:38 john Exp $";
  110. #pragma on (unreferenced)
  111.  
  112. #include <stdio.h>
  113. #include <stdlib.h>
  114. #include <math.h>
  115. #include <string.h>
  116.  
  117. #include "mono.h"
  118. #include "key.h"
  119. #include "gr.h"
  120.  
  121. #include "bm.h"            // for MAX_TEXTURES
  122.  
  123. #include "inferno.h"
  124. #include "segment.h"
  125. #include "editor.h"
  126. #include "error.h"
  127. #include "textures.h"
  128. #include "object.h"
  129.  
  130. #include "gamemine.h"
  131. #include "gameseg.h"
  132.  
  133. #include "ui.h"            // Because texpage.h need UI_WINDOW type
  134. #include "texpage.h"        // For texpage_goto_first
  135.              
  136. #include "medwall.h"
  137. #include "switch.h"
  138.  
  139. #include "dcflib.h"
  140. #include "nocfile.h"
  141. #include "fuelcen.h"
  142.  
  143. #define REMOVE_EXT(s)  (*(strchr( (s), '.' ))='\0')
  144.  
  145. int CreateDefaultNewSegment();
  146.  
  147. static char     current_tmap_list[MAX_TEXTURES][13];
  148.  
  149. // -----------------------------------------------------------------------------
  150. // Save mine will:
  151. // 1. Write file info, header info, editor info, vertex data, segment data,
  152. //    and new_segment in that order, marking their file offset.
  153. // 2. Go through all the fields and fill in the offset, size, and sizeof
  154. //    values in the headers.
  155.  
  156. int med_save_mine(char * filename)
  157. {
  158.     FILE * SaveFile;
  159.     char ErrorMessage[256];
  160.  
  161.     SaveFile = cfopen( filename, CF_WRITE_MODE );
  162.     if (!SaveFile)
  163.     {
  164.         char fname[20];
  165.         _splitpath( filename, NULL, NULL, fname, NULL );
  166.  
  167.         sprintf( ErrorMessage, \
  168.             "ERROR: Cannot write to '%s'.\nYou probably need to check out a locked\nversion of the file. You should save\nthis under a different filename, and then\ncheck out a locked copy by typing\n\'co -l %s.lvl'\nat the DOS prompt.\n" 
  169.             , filename, fname, fname );
  170.         sprintf( ErrorMessage, "ERROR: Unable to open %s\n", filename );
  171.         MessageBox( -2, -2, 1, ErrorMessage, "Ok" );
  172.         return 1;
  173.     }
  174.  
  175.     save_mine_data(SaveFile);
  176.     
  177.     //==================== CLOSE THE FILE =============================
  178.     cfclose(SaveFile);
  179.  
  180.     return 0;
  181.  
  182. }
  183.  
  184. // -----------------------------------------------------------------------------
  185. // saves to an already-open file
  186. int save_mine_data(CFILE * SaveFile)
  187. {
  188.     int  header_offset, editor_offset, vertex_offset, segment_offset, doors_offset, texture_offset, walls_offset, triggers_offset; //, links_offset;
  189.     int  newseg_verts_offset;
  190.     int  newsegment_offset;
  191.     int  i;
  192.  
  193.     med_compress_mine();
  194.     warn_if_concave_segments();
  195.     
  196.     for (i=0;i<NumTextures;i++)
  197.         strncpy(current_tmap_list[i], TmapInfo[i].filename, 13);
  198.  
  199.     //=================== Calculate offsets into file ==================
  200.  
  201.     header_offset = cftell(SaveFile) + sizeof(mine_fileinfo);
  202.     editor_offset = header_offset + sizeof(mine_header);
  203.     texture_offset = editor_offset + sizeof(mine_editor);
  204.     vertex_offset  = texture_offset + (13*NumTextures);
  205.     segment_offset = vertex_offset + (sizeof(vms_vector)*Num_vertices);
  206.     newsegment_offset = segment_offset + (sizeof(segment)*Num_segments);
  207.     newseg_verts_offset = newsegment_offset + sizeof(segment);
  208.     walls_offset = newseg_verts_offset + (sizeof(vms_vector)*8);
  209.     triggers_offset =    walls_offset + (sizeof(wall)*Num_walls);
  210.     doors_offset = triggers_offset + (sizeof(trigger)*Num_triggers);
  211.  
  212.     //===================== SAVE FILE INFO ========================
  213.  
  214.     mine_fileinfo.fileinfo_signature=    0x2884;
  215.     mine_fileinfo.fileinfo_version  =   MINE_VERSION;
  216.     mine_fileinfo.fileinfo_sizeof   =   sizeof(mine_fileinfo);
  217.     mine_fileinfo.header_offset     =   header_offset;
  218.     mine_fileinfo.header_size       =   sizeof(mine_header);
  219.     mine_fileinfo.editor_offset     =   editor_offset;
  220.     mine_fileinfo.editor_size       =   sizeof(mine_editor);
  221.     mine_fileinfo.vertex_offset     =   vertex_offset;
  222.     mine_fileinfo.vertex_howmany    =   Num_vertices;
  223.     mine_fileinfo.vertex_sizeof     =   sizeof(vms_vector);
  224.     mine_fileinfo.segment_offset    =   segment_offset;
  225.     mine_fileinfo.segment_howmany   =   Num_segments;
  226.     mine_fileinfo.segment_sizeof    =   sizeof(segment);
  227.     mine_fileinfo.newseg_verts_offset     =   newseg_verts_offset;
  228.     mine_fileinfo.newseg_verts_howmany    =   8;
  229.     mine_fileinfo.newseg_verts_sizeof     =   sizeof(vms_vector);
  230.     mine_fileinfo.texture_offset    =   texture_offset;
  231.     mine_fileinfo.texture_howmany   =   NumTextures;
  232.     mine_fileinfo.texture_sizeof    =   13;  // num characters in a name
  233.     mine_fileinfo.walls_offset          =    walls_offset;
  234.     mine_fileinfo.walls_howmany      =    Num_walls;
  235.     mine_fileinfo.walls_sizeof          =    sizeof(wall);  
  236.     mine_fileinfo.triggers_offset      =    triggers_offset;
  237.     mine_fileinfo.triggers_howmany  =    Num_triggers;
  238.     mine_fileinfo.triggers_sizeof      =    sizeof(trigger);  
  239.  
  240.     // Write the fileinfo
  241.     cfwrite( &mine_fileinfo, sizeof(mine_fileinfo), 1, SaveFile );
  242.  
  243.     //===================== SAVE HEADER INFO ========================
  244.  
  245.     mine_header.num_vertices        =   Num_vertices;
  246.     mine_header.num_segments        =   Num_segments;
  247.  
  248.     // Write the editor info
  249.     if (header_offset != cftell(SaveFile))
  250.         Error( "OFFSETS WRONG IN MINE.C!" );
  251.  
  252.     cfwrite( &mine_header, sizeof(mine_header), 1, SaveFile );
  253.  
  254.     //===================== SAVE EDITOR INFO ==========================
  255.     mine_editor.current_seg         =   Cursegp - Segments;
  256.     mine_editor.newsegment_offset   =   newsegment_offset; 
  257.     mine_editor.newsegment_size     =   sizeof(segment);
  258.  
  259.     // Next 3 vars added 10/07 by JAS
  260.     mine_editor.Curside             =   Curside;
  261.     if (Markedsegp)
  262.         mine_editor.Markedsegp       =   Markedsegp - Segments;
  263.     else                                      
  264.         mine_editor.Markedsegp       =   -1;
  265.     mine_editor.Markedside          =   Markedside;
  266.     for (i=0;i<10;i++)
  267.         mine_editor.Groupsegp[i]      =    Groupsegp[i] - Segments;
  268.     for (i=0;i<10;i++)
  269.         mine_editor.Groupside[i]     =    Groupside[i];
  270.  
  271.     if (editor_offset != cftell(SaveFile))
  272.         Error( "OFFSETS WRONG IN MINE.C!" );
  273.     cfwrite( &mine_editor, sizeof(mine_editor), 1, SaveFile );
  274.  
  275.     //===================== SAVE TEXTURE INFO ==========================
  276.  
  277.     if (texture_offset != cftell(SaveFile))
  278.         Error( "OFFSETS WRONG IN MINE.C!" );
  279.     cfwrite( current_tmap_list, 13, NumTextures, SaveFile );
  280.     
  281.     //===================== SAVE VERTEX INFO ==========================
  282.  
  283.     if (vertex_offset != cftell(SaveFile))
  284.         Error( "OFFSETS WRONG IN MINE.C!" );
  285.     cfwrite( Vertices, sizeof(vms_vector), Num_vertices, SaveFile );
  286.  
  287.     //===================== SAVE SEGMENT INFO =========================
  288.  
  289.     if (segment_offset != cftell(SaveFile))
  290.         Error( "OFFSETS WRONG IN MINE.C!" );
  291.     cfwrite( Segments, sizeof(segment), Num_segments, SaveFile );
  292.  
  293.     //===================== SAVE NEWSEGMENT INFO ======================
  294.  
  295.     if (newsegment_offset != cftell(SaveFile))
  296.         Error( "OFFSETS WRONG IN MINE.C!" );
  297.     cfwrite( &New_segment, sizeof(segment), 1, SaveFile );
  298.  
  299.     if (newseg_verts_offset != cftell(SaveFile))
  300.         Error( "OFFSETS WRONG IN MINE.C!" );
  301.     cfwrite( &Vertices[New_segment.verts[0]], sizeof(vms_vector), 8, SaveFile );
  302.  
  303.     //==================== CLOSE THE FILE =============================
  304.  
  305.     return 0;
  306.  
  307. }
  308.  
  309.  
  310.  
  311. #define COMPILED_MINE_VERSION 0
  312.  
  313. void dump_fix_as_short( fix value, int nbits, CFILE * SaveFile )
  314. {
  315.     int int_value = (int)(value>>nbits);
  316.     short short_value;
  317.  
  318.     if( int_value > 0x7fff ) {
  319.         short_value = 0x7fff;
  320.         mprintf((1, "Warning: Fix (%8x) won't fit in short.  Saturating to %8x.\n", int_value, short_value<<nbits));
  321.     }
  322.     else if( int_value < -0x7fff ) {
  323.         short_value = -0x7fff;
  324.         mprintf((1, "Warning: Fix (%8x) won't fit in short.  Saturating to %8x.\n", int_value, short_value<<nbits));
  325.     }
  326.     else
  327.         short_value = (short)int_value;
  328.  
  329.     cfwrite( &short_value, sizeof(short_value), 1, SaveFile );
  330. }
  331.  
  332. //version of dump for unsigned values
  333. void dump_fix_as_ushort( fix value, int nbits, CFILE * SaveFile )
  334. {
  335.     uint int_value;
  336.     ushort short_value;
  337.  
  338.     if (value < 0) {
  339.         mprintf((1, "Warning: fix (%8x) is signed...setting to zero.\n", value));
  340.         Int3();        //hey---show this to Matt
  341.         value = 0;
  342.     }
  343.     else
  344.         int_value = value >> nbits;
  345.  
  346.     if( int_value > 0xffff ) {
  347.         short_value = 0xffff;
  348.         mprintf((1, "Warning: Fix (%8x) won't fit in unsigned short.  Saturating to %8x.\n", int_value, short_value<<nbits));
  349.     }
  350.     else
  351.         short_value = int_value;
  352.  
  353.     cfwrite( &short_value, sizeof(short_value), 1, SaveFile );
  354. }
  355.  
  356. int    New_file_format_save = 1;
  357.  
  358. // -----------------------------------------------------------------------------
  359. // saves compiled mine data to an already-open file...
  360. int save_mine_data_compiled(FILE * SaveFile)
  361. {
  362.     short i,segnum,sidenum;
  363.     ubyte version = COMPILED_MINE_VERSION;
  364.  
  365. #ifndef SHAREWARE
  366.     if (New_file_format_save)
  367.         return save_mine_data_compiled_new(SaveFile);
  368. #endif
  369.  
  370.     med_compress_mine();
  371.     warn_if_concave_segments();
  372.  
  373.     if (Highest_segment_index >= MAX_GAME_SEGMENTS) {
  374.         char    message[128];
  375.         sprintf(message, "Error: Too many segments (%i > %i) for game (not editor)", Highest_segment_index+1, MAX_GAME_SEGMENTS);
  376.         MessageBox( -2, -2, 1, message, "Ok" );
  377.     }
  378.  
  379.     if (Highest_vertex_index >= MAX_GAME_VERTICES) {
  380.         char    message[128];
  381.         sprintf(message, "Error: Too many vertices (%i > %i) for game (not editor)", Highest_vertex_index+1, MAX_GAME_VERTICES);
  382.         MessageBox( -2, -2, 1, message, "Ok" );
  383.     }
  384.  
  385.     //=============================== Writing part ==============================
  386.     cfwrite( &version, sizeof(ubyte), 1, SaveFile );                        // 1 byte = compiled version
  387.     cfwrite( &Num_vertices, sizeof(int), 1, SaveFile );                    // 4 bytes = Num_vertices
  388.     cfwrite( &Num_segments, sizeof(int), 1, SaveFile );                        // 4 bytes = Num_segments
  389.     cfwrite( Vertices, sizeof(vms_vector), Num_vertices, SaveFile );
  390.  
  391.     for (segnum=0; segnum<Num_segments; segnum++ )    {
  392.         // Write short Segments[segnum].children[MAX_SIDES_PER_SEGMENT]
  393.          cfwrite( &Segments[segnum].children, sizeof(short), MAX_SIDES_PER_SEGMENT, SaveFile );
  394.         // Write short Segments[segnum].verts[MAX_VERTICES_PER_SEGMENT]
  395.         cfwrite( &Segments[segnum].verts, sizeof(short), MAX_VERTICES_PER_SEGMENT, SaveFile );
  396.         // Write ubyte    Segments[segnum].special
  397.         cfwrite( &Segments[segnum].special, sizeof(ubyte), 1, SaveFile );
  398.         // Write byte    Segments[segnum].matcen_num
  399.         cfwrite( &Segments[segnum].matcen_num, sizeof(ubyte), 1, SaveFile );
  400.         // Write short    Segments[segnum].value
  401.         cfwrite( &Segments[segnum].value, sizeof(short), 1, SaveFile );
  402.         // Write fix    Segments[segnum].static_light (shift down 5 bits, write as short)
  403.         dump_fix_as_ushort( Segments[segnum].static_light, 4, SaveFile );
  404.         //cfwrite( &Segments[segnum].static_light , sizeof(fix), 1, SaveFile );
  405.     
  406.         // Write the walls as a 6 byte array
  407.         for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )    {
  408.             uint wallnum;
  409.             ubyte byte_wallnum;
  410.             if (Segments[segnum].sides[sidenum].wall_num<0)
  411.                 wallnum = 255;        // Use 255 to mark no walls
  412.             else {
  413.                 wallnum = Segments[segnum].sides[sidenum].wall_num;
  414.                 Assert( wallnum < 255 );        // Get John or Mike.. can only store up to 255 walls!!! 
  415.             }
  416.             byte_wallnum = (ubyte)wallnum;
  417.             cfwrite( &byte_wallnum, sizeof(ubyte), 1, SaveFile );
  418.         }
  419.  
  420.         for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )    {
  421.             if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) )    {
  422.                 // Write short Segments[segnum].sides[sidenum].tmap_num;
  423.                 cfwrite( &Segments[segnum].sides[sidenum].tmap_num, sizeof(short), 1, SaveFile );
  424.                 // Write short Segments[segnum].sides[sidenum].tmap_num2;
  425.                 cfwrite( &Segments[segnum].sides[sidenum].tmap_num2, sizeof(short), 1, SaveFile );
  426.                 // Write uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short)
  427.                 for (i=0; i<4; i++ )    {
  428.                     dump_fix_as_short( Segments[segnum].sides[sidenum].uvls[i].u, 5, SaveFile );
  429.                     dump_fix_as_short( Segments[segnum].sides[sidenum].uvls[i].v, 5, SaveFile );
  430.                     dump_fix_as_ushort( Segments[segnum].sides[sidenum].uvls[i].l, 1, SaveFile );
  431.                     //cfwrite( &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1, SaveFile );
  432.                 }    
  433.             }
  434.         }
  435.  
  436.     }
  437.  
  438.     return 0;
  439. }
  440.  
  441. // -----------------------------------------------------------------------------
  442. // saves compiled mine data to an already-open file...
  443. int save_mine_data_compiled_new(FILE * SaveFile)
  444. {
  445.     short        i, segnum, sidenum, temp_short;
  446.     ubyte     version = COMPILED_MINE_VERSION;
  447.     ubyte        bit_mask = 0;
  448.  
  449.     med_compress_mine();
  450.     warn_if_concave_segments();
  451.  
  452.     if (Highest_segment_index >= MAX_GAME_SEGMENTS) {
  453.         char    message[128];
  454.         sprintf(message, "Error: Too many segments (%i > %i) for game (not editor)", Highest_segment_index+1, MAX_GAME_SEGMENTS);
  455.         MessageBox( -2, -2, 1, message, "Ok" );
  456.     }
  457.  
  458.     if (Highest_vertex_index >= MAX_GAME_VERTICES) {
  459.         char    message[128];
  460.         sprintf(message, "Error: Too many vertices (%i > %i) for game (not editor)", Highest_vertex_index+1, MAX_GAME_VERTICES);
  461.         MessageBox( -2, -2, 1, message, "Ok" );
  462.     }
  463.  
  464.     //=============================== Writing part ==============================
  465.     cfwrite( &version, sizeof(ubyte), 1, SaveFile );                        // 1 byte = compiled version
  466.     temp_short = Num_vertices;
  467.     cfwrite( &temp_short, sizeof(short), 1, SaveFile );                    // 2 bytes = Num_vertices
  468.     temp_short = Num_segments;
  469.     cfwrite( &temp_short, sizeof(short), 1, SaveFile );                    // 2 bytes = Num_segments
  470.     cfwrite( Vertices, sizeof(vms_vector), Num_vertices, SaveFile );
  471.  
  472.     for (segnum=0; segnum<Num_segments; segnum++ )    {
  473.  
  474.         for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
  475.              if (Segments[segnum].children[sidenum] != -1)
  476.                 bit_mask |= (1 << sidenum);
  477.         }
  478.  
  479.         if ((Segments[segnum].special != 0) || (Segments[segnum].matcen_num != 0) || (Segments[segnum].value != 0))
  480.             bit_mask |= (1 << MAX_SIDES_PER_SEGMENT);
  481.  
  482.          cfwrite( &bit_mask, sizeof(ubyte), 1, SaveFile );
  483.  
  484.         for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
  485.              if (bit_mask & (1 << sidenum))
  486.                  cfwrite( &Segments[segnum].children[sidenum], sizeof(short), 1, SaveFile );
  487.         }
  488.  
  489.         cfwrite( &Segments[segnum].verts, sizeof(short), MAX_VERTICES_PER_SEGMENT, SaveFile );
  490.  
  491.         if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) {
  492.             cfwrite( &Segments[segnum].special, sizeof(ubyte), 1, SaveFile );
  493.             cfwrite( &Segments[segnum].matcen_num, sizeof(ubyte), 1, SaveFile );
  494.             cfwrite( &Segments[segnum].value, sizeof(short), 1, SaveFile );
  495.         }
  496.  
  497.         dump_fix_as_ushort( Segments[segnum].static_light, 4, SaveFile );
  498.     
  499.         // Write the walls as a 6 byte array
  500.         bit_mask = 0;
  501.         for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )    {
  502.             uint wallnum;
  503.             if (Segments[segnum].sides[sidenum].wall_num >= 0) {
  504.                 bit_mask |= (1 << sidenum);
  505.                 wallnum = Segments[segnum].sides[sidenum].wall_num;
  506.                 Assert( wallnum < 255 );        // Get John or Mike.. can only store up to 255 walls!!! 
  507.             }
  508.         }
  509.         cfwrite( &bit_mask, sizeof(ubyte), 1, SaveFile );
  510.  
  511.         for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )    {
  512.             if (bit_mask & (1 << sidenum))
  513.                 cfwrite( &Segments[segnum].sides[sidenum].wall_num, sizeof(ubyte), 1, SaveFile );
  514.         }
  515.  
  516.         for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )    {
  517.             if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) )    {
  518.                 ushort    tmap_num, tmap_num2;
  519.  
  520.                 tmap_num = Segments[segnum].sides[sidenum].tmap_num;
  521.                 tmap_num2 = Segments[segnum].sides[sidenum].tmap_num2;
  522.                 if (tmap_num2 != 0)
  523.                     tmap_num |= 0x8000;
  524.  
  525.                 cfwrite( &tmap_num, sizeof(ushort), 1, SaveFile );
  526.                 if (tmap_num2 != 0)
  527.                     cfwrite( &tmap_num2, sizeof(ushort), 1, SaveFile );
  528.  
  529.                 for (i=0; i<4; i++ )    {
  530.                     dump_fix_as_short( Segments[segnum].sides[sidenum].uvls[i].u, 5, SaveFile );
  531.                     dump_fix_as_short( Segments[segnum].sides[sidenum].uvls[i].v, 5, SaveFile );
  532.                     dump_fix_as_ushort( Segments[segnum].sides[sidenum].uvls[i].l, 1, SaveFile );
  533.                 }    
  534.             }
  535.         }
  536.  
  537.     }
  538.  
  539.     return 0;
  540. }
  541.  
  542.  
  543.