1 #pragma once
2 
3 //********************************************************************************************
4 //*
5 //*    This file is part of Egoboo.
6 //*
7 //*    Egoboo is free software: you can redistribute it and/or modify it
8 //*    under the terms of the GNU General Public License as published by
9 //*    the Free Software Foundation, either version 3 of the License, or
10 //*    (at your option) any later version.
11 //*
12 //*    Egoboo is distributed in the hope that it will be useful, but
13 //*    WITHOUT ANY WARRANTY; without even the implied warranty of
14 //*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //*    General Public License for more details.
16 //*
17 //*    You should have received a copy of the GNU General Public License
18 //*    along with Egoboo.  If not, see <http://www.gnu.org/licenses/>.
19 //*
20 //********************************************************************************************
21 
22 #include "file_formats/mpd_file.h"
23 #include "extensions/ogl_include.h"
24 
25 #include "lighting.h"
26 #include "bsp.h"
27 
28 //--------------------------------------------------------------------------------------------
29 
30 // struct for holding the mpd data
31 struct s_ego_mpd;
32 typedef struct s_ego_mpd ego_mpd_t;
33 
34 //--------------------------------------------------------------------------------------------
35 //--------------------------------------------------------------------------------------------
36 #define BLOCK_BITS    9
37 #define BLOCK_SIZE    ((float)(1<<(BLOCK_BITS)))
38 
39 #define MAXMESHBLOCKY             (( MAXMESHTILEY >> (BLOCK_BITS-GRID_BITS) )+1)  ///< max blocks in the y direction
40 
41 /// mesh physics
42 #define SLIDE                           0.04f         ///< Acceleration for steep hills
43 #define SLIDEFIX                        0.08f         ///< To make almost flat surfaces flat
44 #define TWIST_FLAT                      119
45 
46 #define TILE_UPPER_SHIFT                8
47 #define TILE_LOWER_MASK                 ((1 << TILE_UPPER_SHIFT)-1)
48 #define TILE_UPPER_MASK                 (~TILE_LOWER_MASK)
49 
50 #define TILE_GET_LOWER_BITS(XX)         ( TILE_LOWER_MASK & (XX) )
51 
52 #define TILE_GET_UPPER_BITS(XX)         (( TILE_UPPER_MASK & (XX) ) >> TILE_UPPER_SHIFT )
53 #define TILE_SET_UPPER_BITS(XX)         (( (XX) << TILE_UPPER_SHIFT ) & TILE_UPPER_MASK )
54 
55 #define TILE_IS_FANOFF(XX)              ( FANOFF == (XX).img )
56 
57 #define TILE_HAS_INVALID_IMAGE(XX)      HAS_SOME_BITS( TILE_UPPER_MASK, (XX).img )
58 
59 //--------------------------------------------------------------------------------------------
60 //--------------------------------------------------------------------------------------------
61 typedef GLXvector3f normal_cache_t[4];
62 typedef float       light_cache_t[4];
63 
64 //--------------------------------------------------------------------------------------------
65 //--------------------------------------------------------------------------------------------
66 //--------------------------------------------------------------------------------------------
67 
68 /// The data describing an Egoboo tile
69 struct s_ego_tile_info
70 {
71     Uint8   type;                              ///< Tile type
72     Uint16  img;                               ///< Get texture from this
73     size_t  vrtstart;                          ///< Which vertex to start at
74 
75     bool_t  fanoff;                            ///< display this tile?
76     bool_t  inrenderlist;                      ///< Is the tile going to be rendered this frame?
77     int     inrenderlist_frame;                ///< What was the frame number the last time this tile was rendered?
78     bool_t  needs_lighting_update;             ///< Has this tile been tagged for a lighting update?
79 
80     oct_bb_t       oct;                        ///< the octagonal bounding box for this tile
81     normal_cache_t ncache;                     ///< the normals at the corners of this tile
82     light_cache_t  lcache;                     ///< the light at the corners of this tile
83     light_cache_t  d1_cache;                   ///< the estimated change in the light at the corner of the tile
84     light_cache_t  d2_cache;                   ///< the estimated change in the light at the corner of the tile
85 };
86 typedef struct s_ego_tile_info ego_tile_info_t;
87 
88 ego_tile_info_t * ego_tile_info_alloc();
89 ego_tile_info_t * ego_tile_info_init( ego_tile_info_t * ptr );
90 
91 ego_tile_info_t * ego_tile_info_alloc_ary( size_t count );
92 ego_tile_info_t * ego_tile_info_init_ary( ego_tile_info_t * ptr, size_t count );
93 
94 //--------------------------------------------------------------------------------------------
95 //--------------------------------------------------------------------------------------------
96 
97 /// The data describing an Egoboo grid
98 struct s_ego_grid_info
99 {
100     Uint8           fx;                        ///< Special effects flags
101     Uint8           twist;                     ///< The orientation of the tile
102 
103     // the lighting info in the upper left hand corner of a grid
104     Uint8            a, l;                     ///< the raw mesh lighting... pretty much ignored
105     lighting_cache_t cache;                    ///< the per-grid lighting info
106 
107 };
108 typedef struct s_ego_grid_info ego_grid_info_t;
109 
110 //--------------------------------------------------------------------------------------------
111 struct s_grid_mem
112 {
113     int             grids_x;                          ///< Size in grids
114     int             grids_y;
115     size_t          grid_count;                       ///< how many grids
116 
117     int             blocks_x;                         ///< Size in blocks
118     int             blocks_y;
119     Uint32          blocks_count;                     ///< Number of blocks (collision areas)
120 
121     float           edge_x;                           ///< Limits
122     float           edge_y;
123 
124     Uint32        * blockstart;                       ///< list of blocks that start each row
125     Uint32        * tilestart;                        ///< list of tiles  that start each row
126 
127     // the per-grid info
128     ego_grid_info_t* grid_list;                        ///< tile command info
129 };
130 typedef struct s_grid_mem grid_mem_t;
131 
132 //--------------------------------------------------------------------------------------------
133 //--------------------------------------------------------------------------------------------
134 
135 /// A wrapper for the dynamically allocated mesh memory
136 struct s_tile_mem
137 {
138     aabb_t           bbox;                             ///< bounding box for the entire mesh
139 
140     // the per-tile info
141     size_t           tile_count;                       ///< number of tiles
142     ego_tile_info_t* tile_list;                        ///< tile command info
143 
144     // the per-vertex info to be presented to OpenGL
145     size_t          vert_count;                        ///< number of vertices
146     GLXvector3f   * plst;                              ///< the position list
147     GLXvector2f   * tlst;                              ///< the texture coordinate list
148     GLXvector3f   * clst;                              ///< the color list (for lighting the mesh)
149     GLXvector3f   * nlst;                              ///< the normal list
150 };
151 typedef struct s_tile_mem tile_mem_t;
152 
153 //--------------------------------------------------------------------------------------------
154 
155 /// The generic parameters describing an ego_mpd
156 struct s_ego_mpd_info
157 {
158     size_t          vertcount;                         ///< For malloc
159 
160     int             tiles_x;                          ///< Size in tiles
161     int             tiles_y;
162     Uint32          tiles_count;                      ///< Number of tiles
163 };
164 typedef struct s_ego_mpd_info ego_mpd_info_t;
165 
166 //--------------------------------------------------------------------------------------------
167 
168 /// Egoboo's representation of the .mpd mesh file
169 struct s_ego_mpd
170 {
171     ego_mpd_info_t  info;
172     tile_mem_t      tmem;
173     grid_mem_t      gmem;
174 
175     fvec2_t         tileoff[MAXTILETYPE];     ///< Tile texture offset
176 };
177 
178 //--------------------------------------------------------------------------------------------
179 //--------------------------------------------------------------------------------------------
180 // struct for caching fome values for wall collisions
181 
182 struct s_mesh_wall_data
183 {
184     int   ix_min, ix_max, iy_min, iy_max;
185     float fx_min, fx_max, fy_min, fy_max;
186 
187     ego_mpd_info_t  * pinfo;
188     ego_tile_info_t * tlist;
189     ego_grid_info_t * glist;
190 };
191 
192 typedef struct s_mesh_wall_data mesh_wall_data_t;
193 //--------------------------------------------------------------------------------------------
194 //--------------------------------------------------------------------------------------------
195 extern fvec3_t   map_twist_nrm[256];
196 extern Uint32    map_twist_y[256];            ///< For surface normal of mesh
197 extern Uint32    map_twist_x[256];
198 extern float     map_twistvel_x[256];            ///< For sliding down steep hills
199 extern float     map_twistvel_y[256];
200 extern float     map_twistvel_z[256];
201 extern Uint8     map_twist_flat[256];
202 
203 extern int mesh_mpdfx_tests;
204 extern int mesh_bound_tests;
205 extern int mesh_pressure_tests;
206 
207 //--------------------------------------------------------------------------------------------
208 //--------------------------------------------------------------------------------------------
209 ego_mpd_t * mesh_create( ego_mpd_t * pmesh, int tiles_x, int tiles_y );
210 bool_t      mesh_destroy( ego_mpd_t ** pmesh );
211 
212 ego_mpd_t * mesh_ctor( ego_mpd_t * pmesh );
213 ego_mpd_t * mesh_dtor( ego_mpd_t * pmesh );
214 ego_mpd_t * mesh_renew( ego_mpd_t * pmesh );
215 
216 /// loading/saving
217 ego_mpd_t * mesh_load( const char *modname, ego_mpd_t * pmesh );
218 
219 void   mesh_make_twist();
220 
221 float  mesh_light_corners( ego_mpd_t * pmesh, int itile, float mesh_lighting_keep );
222 bool_t mesh_test_corners( ego_mpd_t * pmesh, int itile, float threshold );
223 bool_t mesh_interpolate_vertex( tile_mem_t * pmem, int itile, float pos[], float * plight );
224 
225 bool_t grid_light_one_corner( ego_mpd_t * pmesh, int fan, float height, float nrm[], float * plight );
226 
227 BIT_FIELD mesh_hit_wall( const ego_mpd_t * pmesh, const float pos[], const float radius, const Uint32 bits, float nrm[], float * pressure, mesh_wall_data_t * private_data );
228 BIT_FIELD mesh_test_wall( const ego_mpd_t * pmesh, const float pos[], const float radius, const Uint32 bits, mesh_wall_data_t * private_data );
229 
230 float mesh_get_max_vertex_0( const ego_mpd_t * pmesh, int grid_x, int grid_y );
231 float mesh_get_max_vertex_1( const ego_mpd_t * pmesh, int grid_x, int grid_y, float xmin, float ymin, float xmax, float ymax );
232 
233 bool_t mesh_set_texture( ego_mpd_t * pmesh, Uint16 tile, Uint16 image );
234 bool_t mesh_update_texture( ego_mpd_t * pmesh, Uint32 tile );
235 
236 fvec2_t mesh_get_diff( const ego_mpd_t * pmesh, const float pos[], float radius, float center_pressure, BIT_FIELD bits );
237 float mesh_get_pressure( const ego_mpd_t * pmesh, const float pos[], float radius, BIT_FIELD bits );
238 
239 Uint8 cartman_get_fan_twist( const ego_mpd_t * pmesh, Uint32 tile );
240