fast i/o macros
[btb/d2x.git] / main / segment.h
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 #ifndef _SEGMENT_H
15 #define _SEGMENT_H
16
17 #include        "pstypes.h"
18 #include        "fix.h"
19 #include "vecmat.h"
20 //#include "3d.h"
21 //#include "inferno.h"
22 #include "cfile.h"
23
24 // Version 1 - Initial version
25 // Version 2 - Mike changed some shorts to bytes in segments, so incompatible!
26
27 #define SIDE_IS_QUAD    1                       // render side as quadrilateral
28 #define SIDE_IS_TRI_02  2                       // render side as two triangles, triangulated along edge from 0 to 2
29 #define SIDE_IS_TRI_13  3                       // render side as two triangles, triangulated along edge from 1 to 3
30
31 // Set maximum values for segment and face data structures.
32 #define MAX_VERTICES_PER_SEGMENT        8
33 #define MAX_SIDES_PER_SEGMENT           6
34 #define MAX_VERTICES_PER_POLY           4
35 #define WLEFT                                                           0
36 #define WTOP                                                            1
37 #define WRIGHT                                                  2
38 #define WBOTTOM                                                 3
39 #define WBACK                                                           4
40 #define WFRONT                                                  5
41
42 #if defined(SHAREWARE)
43   #define       MAX_SEGMENTS                                    800
44   #define       MAX_SEGMENT_VERTICES                    2800
45 #else
46   #define       MAX_SEGMENTS                                    900
47   #define       MAX_SEGMENT_VERTICES                    3600
48 #endif
49
50 //normal everyday vertices
51
52 #define DEFAULT_LIGHTING                        0                       // (F1_0/2)
53
54 #ifdef EDITOR   //verts for the new segment
55   #define       NUM_NEW_SEG_VERTICES            8
56   #define       NEW_SEGMENT_VERTICES            (MAX_SEGMENT_VERTICES)
57   #define       MAX_VERTICES                            (MAX_SEGMENT_VERTICES+NUM_NEW_SEG_VERTICES)
58 #else           //No editor
59   #define       MAX_VERTICES                            (MAX_SEGMENT_VERTICES)
60 #endif
61
62 //      Returns true if segnum references a child, else returns false.
63 //      Note that -1 means no connection, -2 means a connection to the outside world.
64 #define IS_CHILD(segnum) (segnum > -1)
65
66 //Structure for storing u,v,light values. 
67 //NOTE: this structure should be the same as the one in 3d.h
68 typedef struct uvl {
69         fix u,v,l;
70 } uvl;
71
72 #ifdef COMPACT_SEGS
73 typedef struct side {
74         byte            type;                                                                   // replaces num_faces and tri_edge, 1 = quad, 2 = 0:2 triangulation, 3 = 1:3 triangulation
75         ubyte           pad;                                                                    //keep us longword alligned
76         short           wall_num;
77         short           tmap_num;
78         short           tmap_num2;
79         uvl             uvls[4];
80         // vms_vector   normals[2];                                             // 2 normals, if quadrilateral, both the same.
81 } side;
82 #else
83 typedef struct side {
84         byte            type;                                                                   // replaces num_faces and tri_edge, 1 = quad, 2 = 0:2 triangulation, 3 = 1:3 triangulation
85         ubyte           pad;                                                                    //keep us longword alligned
86         short           wall_num;
87         short           tmap_num;
88         short           tmap_num2;
89         uvl             uvls[4];
90         vms_vector      normals[2];                                             // 2 normals, if quadrilateral, both the same.
91 } side;
92 #endif
93
94 typedef struct segment {
95         #ifdef  EDITOR
96         short           segnum;                                                         // segment number, not sure what it means
97         #endif
98         side            sides[MAX_SIDES_PER_SEGMENT];   // 6 sides
99         short           children[MAX_SIDES_PER_SEGMENT];        // indices of 6 children segments, front, left, top, right, bottom, back
100         short           verts[MAX_VERTICES_PER_SEGMENT];        // vertex ids of 4 front and 4 back vertices
101         #ifdef  EDITOR
102         short           group;                                                          // group number to which the segment belongs.
103         short           objects;                                                                // pointer to objects in this segment
104         #else
105         int             objects;                                                                // pointer to objects in this segment
106         #endif
107
108 // -- Moved to segment2 to make this struct 512 bytes long --
109 //      ubyte           special;                                                                // what type of center this is 
110 //      byte            matcen_num;                                                     //      which center segment is associated with.
111 //      short           value;
112 //      fix             static_light;                                           //average static light in segment
113 //      #ifndef EDITOR
114 //      short           pad;                    //make structure longword aligned
115 //      #endif
116 } segment;
117
118 #define S2F_AMBIENT_WATER               0x01
119 #define S2F_AMBIENT_LAVA                0x02
120
121 typedef struct segment2 {
122         ubyte           special;
123         byte            matcen_num;
124         byte            value;
125         ubyte           s2_flags;
126         fix             static_light;
127 } segment2;
128
129 //values for special field
130 #define SEGMENT_IS_NOTHING                      0
131 #define SEGMENT_IS_FUELCEN                      1
132 #define SEGMENT_IS_REPAIRCEN            2
133 #define SEGMENT_IS_CONTROLCEN           3
134 #define SEGMENT_IS_ROBOTMAKER           4
135 #define SEGMENT_IS_GOAL_BLUE            5
136 #define SEGMENT_IS_GOAL_RED             6
137 #define MAX_CENTER_TYPES                        7
138
139 #ifdef COMPACT_SEGS
140 extern void get_side_normal(segment *sp, int sidenum, int normal_num, vms_vector * vm );
141 extern void get_side_normals(segment *sp, int sidenum, vms_vector * vm1, vms_vector *vm2 );
142 #endif
143
144 //      Local segment data.
145 //      This is stuff specific to a segment that does not need to get written to disk.
146 //      This is a handy separation because we can add to this structure without obsoleting
147 //      existing data on disk.
148 #define SS_REPAIR_CENTER        0x01                            //      Bitmask for this segment being part of repair center.
149
150 //--repair-- typedef struct {
151 //--repair--    int     special_type;
152 //--repair--    short   special_segment;                                                // if special_type indicates repair center, this is the base of the repair center
153 //--repair-- } lsegment;
154
155 typedef struct {
156         int             num_segments;
157         int             num_vertices;
158         short           segments[MAX_SEGMENTS];
159         short           vertices[MAX_VERTICES];
160 } group;
161
162 // Globals from mglobal.c
163 extern  vms_vector      Vertices[];
164 extern  segment         Segments[];
165 extern  segment2                Segment2s[];
166 extern  int                     Num_segments;
167 extern  int                     Num_vertices;
168
169 extern  byte            Side_to_verts[MAX_SIDES_PER_SEGMENT][4];        // Side_to_verts[my_side] is list of vertices forming side my_side.
170 extern  int             Side_to_verts_int[MAX_SIDES_PER_SEGMENT][4];    // Side_to_verts[my_side] is list of vertices forming side my_side.
171 extern  char            Side_opposite[];                                                                        // Side_opposite[my_side] returns side opposite cube from my_side.
172
173 #define SEG_PTR_2_NUM(segptr) (Assert((unsigned) (segptr-Segments)<MAX_SEGMENTS),(segptr)-Segments)
174
175 //      New stuff, 10/14/95: For shooting out lights and monitors.
176 //      Light cast upon vert_light vertices in segnum:sidenum by some light
177 typedef struct {
178         short   segnum;
179         byte    sidenum;
180         byte    dummy;
181         ubyte   vert_light[4];
182 } delta_light;
183
184 //      Light at segnum:sidenum casts light on count sides beginning at index (in array Delta_lights)
185 typedef struct {
186         short   segnum;
187         byte    sidenum;
188         byte    count;
189         short   index;
190 } dl_index;
191
192 #define MAX_DL_INDICES          500
193 #define MAX_DELTA_LIGHTS        10000
194
195 #define DL_SCALE                                2048            //      Divide light to allow 3 bits integer, 5 bits fraction.
196
197 extern  dl_index                Dl_indices[MAX_DL_INDICES];
198 extern  delta_light Delta_lights[MAX_DELTA_LIGHTS];
199 extern  int                     Num_static_lights;
200
201 extern int subtract_light(int segnum, int sidenum);
202 extern int add_light(int segnum, int sidenum);
203 extern void restore_all_lights_in_mine(void);
204 extern void clear_light_subtracted(void);
205
206 extern ubyte Light_subtracted[MAX_SEGMENTS];
207
208 // ----------------------------------------------------------------------------------------------------------
209 // --------------------------  Segment interrogation functions ------------------------
210 //       Do NOT read the segment data structure directly.  Use these functions instead.
211 //                      The segment data structure is GUARANTEED to change MANY TIMES.  If you read the
212 //                      segment data structure directly, your code will break, I PROMISE IT!
213 //      Return a pointer to the list of vertex indices for the current segment in vp and
214 //      the number of vertices in *nv.
215 extern void med_get_vertex_list(segment *s,int *nv,short **vp);
216
217 //      Return a pointer to the list of vertex indices for face facenum in vp and
218 //      the number of vertices in *nv.
219 extern void med_get_face_vertex_list(segment *s,int side, int facenum,int *nv,short **vp);
220
221 //      Set *nf = number of faces in segment s.
222 extern void med_get_num_faces(segment *s,int *nf);
223
224 void med_validate_segment_side(segment *sp,int side);
225
226 // Delete segment function added for curves.c
227 extern int med_delete_segment(segment *sp);
228
229 //      Delete segment from group
230 extern void delete_segment_from_group(int segment_num, int group_num);
231
232 //      Add segment to group
233 extern void add_segment_to_group(int segment_num, int group_num);
234
235 // Verify that all vertices are legal.
236 extern void med_check_all_vertices();
237
238 #ifdef FAST_FILE_IO
239 #define segment2_read(s2, fp) cfread(s2, sizeof(segment2), 1, fp)
240 #define delta_light_read(dl, fp) cfread(dl, sizeof(delta_light), 1, fp)
241 #define dl_index_read(di, fp) cfread(di, sizeof(dl_index), 1, fp)
242 #else
243 /*
244  * reads a segment2 structure from a CFILE
245  */
246 void segment2_read(segment2 *s2, CFILE *fp);
247
248 /*
249  * reads a delta_light structure from a CFILE
250  */
251 void delta_light_read(delta_light *dl, CFILE *fp);
252
253 /*
254  * reads a dl_index structure from a CFILE
255  */
256 void dl_index_read(dl_index *di, CFILE *fp);
257 #endif
258
259 #endif