mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-17 14:00:25 +02:00
841 lines
21 KiB
C
841 lines
21 KiB
C
/*
|
|
STRUCTURES.C
|
|
|
|
symbols in this file:
|
|
00187C10 0010:
|
|
_structures_initialize (0000)
|
|
00187C20 0010:
|
|
_structures_initialize_for_new_map (0000)
|
|
00187C30 0010:
|
|
_structures_dispose_from_old_map (0000)
|
|
00187C40 0010:
|
|
_structures_dispose (0000)
|
|
00187C50 0040:
|
|
_structure_cluster_marker_begin (0000)
|
|
00187C90 0080:
|
|
_structure_cluster_unmarked (0000)
|
|
00187D10 0080:
|
|
_structure_cluster_mark (0000)
|
|
00187D90 0040:
|
|
_structure_cluster_marker_end (0000)
|
|
00187DD0 01b0:
|
|
_structure_render_surface_from_point_and_leaf (0000)
|
|
00187F80 00d0:
|
|
_structure_get_planar_fog_definition_index (0000)
|
|
00188050 01b0:
|
|
_sphere_intersects_cluster_portal (0000)
|
|
00188200 0120:
|
|
_code_00188200 (0000)
|
|
00188320 01e0:
|
|
_structure_clusters_in_cone (0000)
|
|
00188500 0260:
|
|
_structure_test_vector (0000)
|
|
00188760 01c0:
|
|
_structure_get_planar_fog (0000)
|
|
00188920 0160:
|
|
_render_debug_fog_planes (0000)
|
|
00188A80 0130:
|
|
_structure_clusters_in_sphere (0000)
|
|
002A1E54 002e:
|
|
??_C@_0CO@IAFCMJGA@?$CBstructure_globals?4cluster_marke@ (0000)
|
|
002A1E84 0027:
|
|
??_C@_0CH@MEPFLBCJ@c?3?2halo?2SOURCE?2structures?2struct@ (0000)
|
|
002A1EAC 002d:
|
|
??_C@_0CN@MDKOILJF@structure_globals?4cluster_marker@ (0000)
|
|
002A1EDC 002b:
|
|
??_C@_0CL@OOHBKJHI@stack_depth?$DMMAXIMUM_CLUSTERS_PER@ (0000)
|
|
002A1F08 0002:
|
|
??_C@_01LKDEMHDF@s?$AA@ (0000)
|
|
002A1F0C 000e:
|
|
??_C@_0O@GNJLHEFA@surface_index?$AA@ (0000)
|
|
002A1F1C 000f:
|
|
??_C@_0P@MLEINILI@material_index?$AA@ (0000)
|
|
002A1F2C 0014:
|
|
??_C@_0BE@GKJHHJJB@intersected_indices?$AA@ (0000)
|
|
004C1100 0808:
|
|
_bss_004c1100 (0000)
|
|
*/
|
|
|
|
/* ---------- headers */
|
|
|
|
#include "cseries/cseries.h"
|
|
#include "math/real_math.h"
|
|
#include "physics/collision_bsp_definitions.h"
|
|
#include "physics/collisions.h"
|
|
#include "physics/collision_usage.h"
|
|
#include "rasterizer/rasterizer.h"
|
|
#include "rasterizer/rasterizer_debug.h"
|
|
#include "rasterizer/rasterizer_geometry_environment.h"
|
|
#include "render/render.h"
|
|
#include "scenario/scenario.h"
|
|
#include "scenario/fog_definitions.h"
|
|
#include "scenario/sky_definitions.h"
|
|
#include "structure_bsp_definitions.h"
|
|
#include "structure_vector_tests.h"
|
|
#include "structures.h"
|
|
|
|
/* ---------- constants */
|
|
|
|
enum
|
|
{
|
|
_render_planar_fog_mode_off = 0,
|
|
_render_planar_fog_mode_normal = 1,
|
|
_render_planar_fog_mode_fully_fogged,
|
|
_render_fog_runtime_screen_use_sky_interpolator_bit = 0,
|
|
_collision_surface_two_sided_bit = 0,
|
|
};
|
|
|
|
/* ---------- macros */
|
|
|
|
#define structure_material_get_vertex(material, vertex_index) \
|
|
((struct environment_vertex_compressed const *) \
|
|
(material)->compressed_vertex_data.address + (vertex_index))
|
|
|
|
/* ---------- structures */
|
|
|
|
struct structure_runtime_globals
|
|
{
|
|
boolean initialized;
|
|
boolean cluster_marker_initialized;
|
|
byte reserved0002[2];
|
|
long cluster_marker;
|
|
long cluster_magic_numbers[MAXIMUM_CLUSTERS_PER_STRUCTURE];
|
|
};
|
|
|
|
struct structure_fog_plane_render
|
|
{
|
|
short region_index;
|
|
word pad;
|
|
real_plane3d plane;
|
|
struct tag_block vertices;
|
|
};
|
|
|
|
struct structure_cluster_graph
|
|
{
|
|
short sky_index;
|
|
short fog_designator;
|
|
short background_sound_palette_index;
|
|
short sound_environment_palette_index;
|
|
short weather_palette_index;
|
|
short transition_structure_bsp_index;
|
|
short first_runtime_decal_index;
|
|
word runtime_decal_count;
|
|
long unused[6];
|
|
struct tag_block predicted_resources;
|
|
struct tag_block subclusters;
|
|
word first_lens_flare_marker_index;
|
|
word lens_flare_marker_count;
|
|
struct tag_block surface_indices;
|
|
struct tag_block mirrors;
|
|
struct tag_block portal_indices;
|
|
};
|
|
|
|
struct structure_cluster_portal
|
|
{
|
|
short cluster_indices[2];
|
|
long plane_index;
|
|
real_point3d centroid;
|
|
real bounding_radius;
|
|
unsigned long flags;
|
|
long unused[6];
|
|
struct tag_block vertices;
|
|
};
|
|
|
|
struct structure_surface_reference
|
|
{
|
|
long surface_index;
|
|
long bsp3d_node_index;
|
|
};
|
|
|
|
struct environment_vertex_compressed
|
|
{
|
|
real_point3d position;
|
|
unsigned long normal;
|
|
unsigned long binormal;
|
|
unsigned long tangent;
|
|
real_point2d texcoord;
|
|
};
|
|
|
|
struct fog_screen
|
|
{
|
|
word flags;
|
|
short layer_count;
|
|
real near_distance;
|
|
real far_distance;
|
|
real near_density;
|
|
real far_density;
|
|
real start_distance_from_fog_plane;
|
|
byte reserved18[4];
|
|
pixel32 color;
|
|
real rotation_multiplier;
|
|
real strafing_multiplier;
|
|
real zoom_multiplier;
|
|
byte reserved2C[8];
|
|
real map_scale;
|
|
struct tag_reference map;
|
|
};
|
|
|
|
struct structure_planar_fog_definition
|
|
{
|
|
word flags;
|
|
word pad;
|
|
real animation_distance;
|
|
byte unused08[0x50];
|
|
real maximum_density;
|
|
byte unused5C[4];
|
|
real maximum_distance;
|
|
byte unused64[4];
|
|
real maximum_depth;
|
|
byte unused6C[0xC];
|
|
real_rgb_color color;
|
|
struct fog_screen screen;
|
|
};
|
|
|
|
typedef char verify_structure_fog_plane_render_size[
|
|
sizeof(struct structure_fog_plane_render) == 0x20 ? 1 : -1];
|
|
typedef char verify_structure_cluster_graph_size[
|
|
sizeof(struct structure_cluster_graph) == 0x68 ? 1 : -1];
|
|
typedef char verify_structure_cluster_graph_portal_indices_offset[
|
|
offsetof(struct structure_cluster_graph, portal_indices) == 0x5C ? 1 : -1];
|
|
typedef char verify_structure_cluster_portal_size[
|
|
sizeof(struct structure_cluster_portal) == 0x40 ? 1 : -1];
|
|
typedef char verify_structure_surface_reference_size[
|
|
sizeof(struct structure_surface_reference) == 0x8 ? 1 : -1];
|
|
typedef char verify_environment_vertex_compressed_size[
|
|
sizeof(struct environment_vertex_compressed) == 0x20 ? 1 : -1];
|
|
typedef char verify_structure_planar_fog_definition_screen_offset[
|
|
offsetof(struct structure_planar_fog_definition, screen) == 0x84 ? 1 : -1];
|
|
|
|
typedef char verify_structure_cluster_marker_initialized_offset[
|
|
offsetof(
|
|
struct structure_runtime_globals,
|
|
cluster_marker_initialized) == 0x1 ? 1 : -1];
|
|
typedef char verify_structure_cluster_marker_offset[
|
|
offsetof(
|
|
struct structure_runtime_globals,
|
|
cluster_marker) == 0x4 ? 1 : -1];
|
|
typedef char verify_structure_cluster_magic_numbers_offset[
|
|
offsetof(
|
|
struct structure_runtime_globals,
|
|
cluster_magic_numbers) == 0x8 ? 1 : -1];
|
|
typedef char verify_structure_runtime_globals_size[
|
|
sizeof(struct structure_runtime_globals) == 0x808 ? 1 : -1];
|
|
|
|
/* ---------- prototypes */
|
|
|
|
/* ---------- globals */
|
|
|
|
static struct structure_runtime_globals structure_globals;
|
|
|
|
extern boolean debug_fog_planes;
|
|
|
|
/* ---------- public code */
|
|
|
|
void structures_initialize(
|
|
void)
|
|
{
|
|
structure_detail_objects_initialize();
|
|
structure_decals_initialize();
|
|
return;
|
|
}
|
|
|
|
void structures_initialize_for_new_map(
|
|
void)
|
|
{
|
|
structure_detail_objects_initialize_for_new_map();
|
|
structure_decals_initialize_for_new_map();
|
|
return;
|
|
}
|
|
|
|
void structures_dispose_from_old_map(
|
|
void)
|
|
{
|
|
structure_decals_dispose_from_old_map();
|
|
structure_detail_objects_dispose_from_old_map();
|
|
return;
|
|
}
|
|
|
|
void structures_dispose(
|
|
void)
|
|
{
|
|
structure_decals_dispose();
|
|
structure_detail_objects_dispose();
|
|
return;
|
|
}
|
|
|
|
void structure_cluster_marker_begin(
|
|
void)
|
|
{
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x103,
|
|
!structure_globals.cluster_marker_initialized);
|
|
structure_globals.cluster_marker++;
|
|
structure_globals.cluster_marker_initialized = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
void structure_cluster_marker_end(
|
|
void)
|
|
{
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x130,
|
|
structure_globals.cluster_marker_initialized);
|
|
structure_globals.cluster_marker_initialized = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
boolean structure_cluster_unmarked(
|
|
short cluster_index)
|
|
{
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x10E,
|
|
structure_globals.cluster_marker_initialized);
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x10F,
|
|
cluster_index>=0 && cluster_index<MAXIMUM_CLUSTERS_PER_STRUCTURE);
|
|
|
|
return structure_globals.cluster_magic_numbers[cluster_index] !=
|
|
structure_globals.cluster_marker;
|
|
}
|
|
|
|
boolean structure_cluster_mark(
|
|
short cluster_index)
|
|
{
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x11E,
|
|
structure_globals.cluster_marker_initialized);
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x11F,
|
|
cluster_index>=0 && cluster_index<MAXIMUM_CLUSTERS_PER_STRUCTURE);
|
|
|
|
if (structure_globals.cluster_magic_numbers[cluster_index] ==
|
|
structure_globals.cluster_marker)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
structure_globals.cluster_magic_numbers[cluster_index] =
|
|
structure_globals.cluster_marker;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
boolean structure_render_surface_from_point_and_leaf(
|
|
real_point3d const *point,
|
|
long leaf_index,
|
|
long plane_index,
|
|
short *lightmap_index,
|
|
short *material_index,
|
|
long *surface_index,
|
|
real *s,
|
|
real *t)
|
|
{
|
|
struct structure_bsp *structure = global_structure_bsp_get();
|
|
struct structure_leaf *leaf = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->leaves,
|
|
leaf_index & LONG_MAX,
|
|
struct structure_leaf);
|
|
long surface_reference_index;
|
|
|
|
for (surface_reference_index = leaf->first_surface_reference_index;
|
|
surface_reference_index <
|
|
leaf->first_surface_reference_index + leaf->surface_reference_count;
|
|
surface_reference_index++)
|
|
{
|
|
struct structure_surface_reference *surface_reference = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->surface_references,
|
|
surface_reference_index,
|
|
struct structure_surface_reference);
|
|
long bsp3d_node_index = surface_reference->bsp3d_node_index;
|
|
|
|
if (bsp3d_node_index != NONE)
|
|
{
|
|
struct collision_bsp *collision_bsp = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->collision_bsp,
|
|
0,
|
|
struct collision_bsp);
|
|
struct bsp3d_node *node = TAG_BLOCK_GET_ELEMENT(
|
|
&collision_bsp->bsp3d.nodes,
|
|
bsp3d_node_index,
|
|
struct bsp3d_node);
|
|
|
|
if (node->plane_designator == plane_index)
|
|
{
|
|
struct structure_surface *surface = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->surfaces,
|
|
surface_reference->surface_index,
|
|
struct structure_surface);
|
|
struct structure_lightmap *lightmap;
|
|
struct structure_material *material;
|
|
|
|
structure_bsp_find_material_for_surface(
|
|
structure,
|
|
surface_reference->surface_index,
|
|
lightmap_index,
|
|
material_index);
|
|
lightmap = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->lightmaps,
|
|
*lightmap_index,
|
|
struct structure_lightmap);
|
|
material = TAG_BLOCK_GET_ELEMENT(
|
|
&lightmap->materials,
|
|
*material_index,
|
|
struct structure_material);
|
|
|
|
if (material->vertices.type ==
|
|
_rasterizer_vertex_type_environment_uncompressed ||
|
|
material->vertices.type ==
|
|
_rasterizer_vertex_type_environment_compressed)
|
|
{
|
|
real_point3d triangle_points[NUMBER_OF_VERTICES_PER_TRIANGLE];
|
|
|
|
environment_vertex_compressed_get_point(
|
|
structure_material_get_vertex(
|
|
material,
|
|
surface->vertex_indices[0]),
|
|
&triangle_points[0]);
|
|
environment_vertex_compressed_get_point(
|
|
structure_material_get_vertex(
|
|
material,
|
|
surface->vertex_indices[1]),
|
|
&triangle_points[1]);
|
|
environment_vertex_compressed_get_point(
|
|
structure_material_get_vertex(
|
|
material,
|
|
surface->vertex_indices[2]),
|
|
&triangle_points[2]);
|
|
|
|
if (point_in_triangle3d(
|
|
point,
|
|
&triangle_points[0],
|
|
&triangle_points[1],
|
|
&triangle_points[2],
|
|
s,
|
|
t))
|
|
{
|
|
*surface_index = surface_reference->surface_index;
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void render_debug_fog_planes(
|
|
void)
|
|
{
|
|
if (debug_fog_planes &&
|
|
render.fog.planar_mode == _render_planar_fog_mode_normal &&
|
|
render.cluster_index != NONE)
|
|
{
|
|
struct structure_bsp *structure = global_structure_bsp_get();
|
|
struct structure_cluster *cluster = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->clusters,
|
|
render.cluster_index,
|
|
struct structure_cluster);
|
|
struct structure_fog_plane_render *fog_plane = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->fog_planes,
|
|
cluster->fog_reference & SHORT_MAX,
|
|
struct structure_fog_plane_render);
|
|
long vertex_count = fog_plane->vertices.count;
|
|
|
|
if (vertex_count > 0)
|
|
{
|
|
short vertex_index = 0;
|
|
|
|
do
|
|
{
|
|
short next_vertex_index = (short)((vertex_index + 1) % vertex_count);
|
|
real_point3d *point0 = TAG_BLOCK_GET_ELEMENT(
|
|
&fog_plane->vertices,
|
|
vertex_index,
|
|
real_point3d);
|
|
real_point3d *point1 = TAG_BLOCK_GET_ELEMENT(
|
|
&fog_plane->vertices,
|
|
next_vertex_index,
|
|
real_point3d);
|
|
real offset = -render.fog.planar_maximum_distance;
|
|
real_point3d offset_point0;
|
|
real_point3d offset_point1;
|
|
|
|
offset_point0.x = point0->x + fog_plane->plane.n.i * offset;
|
|
offset_point0.y = point0->y + fog_plane->plane.n.j * offset;
|
|
offset_point0.z = point0->z + fog_plane->plane.n.k * offset;
|
|
offset_point1.x = point1->x + fog_plane->plane.n.i * offset;
|
|
offset_point1.y = point1->y + fog_plane->plane.n.j * offset;
|
|
offset_point1.z = point1->z + fog_plane->plane.n.k * offset;
|
|
|
|
rasterizer_debug_line(point0, point1, global_real_argb_white);
|
|
rasterizer_debug_line(
|
|
&offset_point0,
|
|
&offset_point1,
|
|
global_real_argb_black);
|
|
rasterizer_debug_line_shaded(
|
|
point0,
|
|
&offset_point0,
|
|
global_real_argb_white,
|
|
global_real_argb_black);
|
|
rasterizer_debug_line_shaded(
|
|
point1,
|
|
&offset_point1,
|
|
global_real_argb_white,
|
|
global_real_argb_black);
|
|
|
|
vertex_count = fog_plane->vertices.count;
|
|
vertex_index++;
|
|
}
|
|
while (vertex_index < vertex_count);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
short structure_clusters_in_cone(
|
|
short position_cluster_index,
|
|
real_point3d const *position,
|
|
real_vector3d const *direction,
|
|
real distance,
|
|
real sine,
|
|
real cosine,
|
|
short maximum_cluster_count,
|
|
short *cluster_indices)
|
|
{
|
|
short cluster_stack[MAXIMUM_CLUSTERS_PER_STRUCTURE];
|
|
short stack_depth;
|
|
short cluster_count = 0;
|
|
struct structure_bsp *structure;
|
|
|
|
structure_cluster_marker_begin();
|
|
structure = global_structure_bsp_get();
|
|
structure_cluster_mark(position_cluster_index);
|
|
cluster_stack[0] = position_cluster_index;
|
|
stack_depth = 1;
|
|
|
|
while (cluster_count < maximum_cluster_count && stack_depth > 0)
|
|
{
|
|
short cluster_index = cluster_stack[--stack_depth];
|
|
struct structure_cluster_graph *cluster = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->clusters,
|
|
cluster_index,
|
|
struct structure_cluster_graph);
|
|
short portal_index;
|
|
|
|
cluster_indices[cluster_count++] = cluster_index;
|
|
|
|
for (portal_index = 0;
|
|
portal_index < cluster->portal_indices.count;
|
|
portal_index++)
|
|
{
|
|
short structure_portal_index = *TAG_BLOCK_GET_ELEMENT(
|
|
&cluster->portal_indices,
|
|
portal_index,
|
|
short);
|
|
struct structure_cluster_portal *portal = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->cluster_portals,
|
|
structure_portal_index,
|
|
struct structure_cluster_portal);
|
|
short adjacent_cluster_index =
|
|
portal->cluster_indices[0] == cluster_index
|
|
? portal->cluster_indices[1]
|
|
: portal->cluster_indices[0];
|
|
|
|
if (structure_cluster_unmarked(adjacent_cluster_index) &&
|
|
sphere_intersects_cone3d(
|
|
&portal->centroid,
|
|
portal->bounding_radius,
|
|
position,
|
|
direction,
|
|
distance,
|
|
sine,
|
|
cosine))
|
|
{
|
|
structure_cluster_mark(adjacent_cluster_index);
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0xF5,
|
|
stack_depth<MAXIMUM_CLUSTERS_PER_STRUCTURE);
|
|
cluster_stack[stack_depth++] = adjacent_cluster_index;
|
|
}
|
|
}
|
|
}
|
|
|
|
structure_cluster_marker_end();
|
|
|
|
return cluster_count;
|
|
}
|
|
|
|
boolean structure_test_vector(
|
|
real_point3d const *p,
|
|
real_vector3d const *v,
|
|
real_point3d *collision_point,
|
|
short *lightmap_index,
|
|
short *material_index,
|
|
long *surface_index,
|
|
real *s,
|
|
real *t)
|
|
{
|
|
boolean found = FALSE;
|
|
boolean done;
|
|
struct collision_result collision;
|
|
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x188,
|
|
p);
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x189,
|
|
v);
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x18A,
|
|
material_index);
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x18B,
|
|
surface_index);
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x18C,
|
|
s);
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x18D,
|
|
t);
|
|
|
|
*collision_point = *p;
|
|
do
|
|
{
|
|
done = TRUE;
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x196,
|
|
global_current_collision_user_depth < MAXIMUM_COLLISION_USER_STACK_DEPTH);
|
|
global_current_collision_users[global_current_collision_user_depth++] =
|
|
_collision_user_structure_lighting;
|
|
|
|
if (collision_test_vector(
|
|
FLAG(_collision_test_front_facing_surfaces_bit) |
|
|
FLAG(_collision_test_structure_bit),
|
|
collision_point,
|
|
v,
|
|
NONE,
|
|
&collision))
|
|
{
|
|
struct structure_bsp *structure = global_structure_bsp_get();
|
|
|
|
*collision_point = collision.point;
|
|
if (structure_render_surface_from_point_and_leaf(
|
|
collision_point,
|
|
collision.location.leaf_index,
|
|
collision.plane_designator & LONG_MAX,
|
|
lightmap_index,
|
|
material_index,
|
|
surface_index,
|
|
s,
|
|
t) &&
|
|
TAG_BLOCK_GET_ELEMENT(
|
|
&structure->lightmaps,
|
|
*lightmap_index,
|
|
struct structure_lightmap)->bitmap_index != NONE)
|
|
{
|
|
found = TRUE;
|
|
}
|
|
else if (TEST_FLAG(
|
|
collision.flags,
|
|
_collision_surface_two_sided_bit))
|
|
{
|
|
done = FALSE;
|
|
collision_point->x += v->i * (1.0f / 4096.0f);
|
|
collision_point->y += v->j * (1.0f / 4096.0f);
|
|
collision_point->z += v->k * (1.0f / 4096.0f);
|
|
}
|
|
}
|
|
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x1AA,
|
|
global_current_collision_user_depth > 1);
|
|
--global_current_collision_user_depth;
|
|
}
|
|
while (!done);
|
|
|
|
return found;
|
|
}
|
|
|
|
long structure_get_planar_fog_definition_index(
|
|
struct structure_bsp const *structure,
|
|
short cluster_index,
|
|
boolean get_fog_from_sky)
|
|
{
|
|
long fog_definition_index = NONE;
|
|
|
|
if (cluster_index != NONE)
|
|
{
|
|
struct structure_cluster *cluster = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->clusters,
|
|
cluster_index,
|
|
struct structure_cluster);
|
|
|
|
if (get_fog_from_sky)
|
|
{
|
|
struct sky *sky = scenario_get_sky(0);
|
|
|
|
if (sky)
|
|
{
|
|
fog_definition_index = sky->indoor_fog_screen.index;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
short fog_designator = cluster->fog_reference;
|
|
|
|
if (fog_designator != NONE)
|
|
{
|
|
short fog_region_index;
|
|
|
|
if (TEST_FLAG((word)fog_designator, SHORT_BITS - 1))
|
|
{
|
|
struct structure_fog_plane_render *fog_plane = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->fog_planes,
|
|
fog_designator & SHORT_MAX,
|
|
struct structure_fog_plane_render);
|
|
|
|
fog_region_index = fog_plane->region_index;
|
|
}
|
|
else
|
|
{
|
|
fog_region_index = fog_designator & SHORT_MAX;
|
|
}
|
|
|
|
if (fog_region_index != NONE)
|
|
{
|
|
struct structure_fog_region *fog_region = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->fog_regions,
|
|
fog_region_index,
|
|
struct structure_fog_region);
|
|
|
|
if (fog_region->fog_palette_index != NONE)
|
|
{
|
|
struct structure_fog_palette_entry *fog_palette =
|
|
TAG_BLOCK_GET_ELEMENT(
|
|
&structure->fog_palette,
|
|
fog_region->fog_palette_index,
|
|
struct structure_fog_palette_entry);
|
|
|
|
fog_definition_index = fog_palette->fog.index;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return fog_definition_index;
|
|
}
|
|
|
|
void structure_get_planar_fog(
|
|
short cluster_index,
|
|
struct render_fog *fog)
|
|
{
|
|
struct structure_bsp *structure = global_structure_bsp_get();
|
|
boolean screen_fog = FALSE;
|
|
long fog_definition_index;
|
|
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structures.c",
|
|
0x1F1,
|
|
fog);
|
|
|
|
fog->planar_mode = _render_planar_fog_mode_off;
|
|
fog->fog_definition_flags = 0;
|
|
fog->screen = NULL;
|
|
|
|
fog_definition_index = structure_get_planar_fog_definition_index(
|
|
structure,
|
|
cluster_index,
|
|
FALSE);
|
|
if (fog_definition_index == NONE)
|
|
{
|
|
fog_definition_index = structure_get_planar_fog_definition_index(
|
|
structure,
|
|
cluster_index,
|
|
TRUE);
|
|
screen_fog = TRUE;
|
|
}
|
|
|
|
if (fog_definition_index != NONE)
|
|
{
|
|
struct structure_cluster *cluster = TAG_BLOCK_GET_ELEMENT(
|
|
&global_structure_bsp_get()->clusters,
|
|
cluster_index,
|
|
struct structure_cluster);
|
|
struct structure_planar_fog_definition *definition =
|
|
(struct structure_planar_fog_definition *)fog_definition_get(
|
|
fog_definition_index);
|
|
|
|
if (screen_fog)
|
|
{
|
|
SET_FLAG(
|
|
fog->runtime_flags,
|
|
_render_fog_runtime_screen_use_sky_interpolator_bit,
|
|
TRUE);
|
|
}
|
|
else
|
|
{
|
|
if (TEST_FLAG((word)cluster->fog_reference, SHORT_BITS - 1))
|
|
{
|
|
struct structure_fog_plane_render *fog_plane = TAG_BLOCK_GET_ELEMENT(
|
|
&structure->fog_planes,
|
|
cluster->fog_reference & SHORT_MAX,
|
|
struct structure_fog_plane_render);
|
|
|
|
fog->planar_mode = _render_planar_fog_mode_normal;
|
|
fog->plane = fog_plane->plane;
|
|
}
|
|
else
|
|
{
|
|
fog->planar_mode = _render_planar_fog_mode_fully_fogged;
|
|
}
|
|
|
|
fog->planar_color = definition->color;
|
|
fog->planar_maximum_density = definition->maximum_density;
|
|
fog->planar_maximum_distance = definition->maximum_distance;
|
|
fog->planar_maximum_depth = definition->maximum_depth;
|
|
|
|
if (TEST_FLAG((word)cluster->fog_reference, SHORT_BITS - 1))
|
|
{
|
|
/* BUG: January and two independent later reconstructions scale
|
|
* the authored animation distance by a literal zero, disabling
|
|
* planar-fog motion. */
|
|
real offset = definition->animation_distance * 0.0f;
|
|
real_vector3d offset_vector;
|
|
|
|
fog->plane.d += offset;
|
|
offset_vector.i = fog->plane.n.i * offset;
|
|
offset_vector.j = fog->plane.n.j * offset;
|
|
offset_vector.k = fog->plane.n.k * offset;
|
|
structure_render_set_fog_offset(&offset_vector);
|
|
}
|
|
}
|
|
|
|
fog->fog_definition_flags = definition->flags;
|
|
fog->screen = &definition->screen;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/* ---------- private code */
|