mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-18 01:00:26 +02:00
Lane D refresh packet 7: +80 padded bytes strict exact; structure_detail_objects.obj is now a whole-object match (15/15 functions, .text/.rdata/.bss all 100%). Zero stable-verdict regressions. The production `struct detail_object_globals debug_detail_objects` aggregate and its `#define detail_object_global_runtime_data` alias were invented. HCEA (DIA2Dump on the structure_detail_objects compiland) lists the file statics detail_object_global_runtime_data (struct pointer), fudge_vector (uchar), fudge_offset and final_offset (float), with debug_detail_objects as a separate global; January's own assert string uses the bare name detail_object_global_runtime_data. The source now declares those statics in January's .bss order (initialised, so VC7 keeps declaration order) and _structure_detail_objects_initialize stores through the global directly, as the debug build does. - symbols.json: four "static": true entries after _debug_detail_objects (line insertion only). - parked.json: unpark _structure_detail_objects_initialize. Gate: ninja PASS, parks 124 active / 0 stale / 0 invalid, admission 0 contradicted / 0 revoked, fake scan 0 leads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
631 lines
17 KiB
C
631 lines
17 KiB
C
/*
|
|
STRUCTURE_DETAIL_OBJECTS.C
|
|
|
|
symbols in this file:
|
|
00183160 0020:
|
|
_calculate_world_from_cell_index_and_offset (0000)
|
|
00183180 0040:
|
|
_get_local_player_datum (0000)
|
|
001831C0 0050:
|
|
_structure_detail_objects_initialize (0000)
|
|
00183210 0010:
|
|
_structure_detail_objects_dispose_from_old_map (0000)
|
|
00183220 0010:
|
|
_structure_detail_objects_dispose (0000)
|
|
00183230 0010:
|
|
_structure_detail_objects_flush (0000)
|
|
00183240 0030:
|
|
_detail_object_offset (0000)
|
|
00183270 0030:
|
|
_key_compare_cells_lower_bound (0000)
|
|
001832A0 0030:
|
|
_key_compare_cells_upper_bound (0000)
|
|
001832D0 0080:
|
|
_get_lower_bound_cell (0000)
|
|
00183350 0080:
|
|
_get_upper_bound_cell (0000)
|
|
001833D0 0030:
|
|
_dot_product4d (0000)
|
|
00183400 0050:
|
|
_structure_detail_objects_initialize_for_new_map (0000)
|
|
00183450 0470:
|
|
_structure_render_detail_objects (0000)
|
|
001838C0 02f0:
|
|
_render_debug_detail_objects (0000)
|
|
002A12BC 0016:
|
|
??_C@_0BG@BEHEKGEA@local_player_index?$DN?$DN0?$AA@ (0000)
|
|
002A12D4 0035:
|
|
??_C@_0DF@DGEAAFAE@c?3?2halo?2SOURCE?2structures?2struct@ (0000)
|
|
002A130C 0019:
|
|
??_C@_0BJ@IOENOFIB@structure?5detail?5objects?$AA@ (0000)
|
|
002A1328 0022:
|
|
??_C@_0CC@GPGHNCNI@detail_object_global_runtime_dat@ (0000)
|
|
002A134C 0023:
|
|
??_C@_0CD@OMDCMBBI@lower_bound_cell?$DM?$DNupper_bound_ce@ (0000)
|
|
004C0CBC 0014:
|
|
_debug_detail_objects (0000)
|
|
*/
|
|
|
|
/* ---------- headers */
|
|
|
|
#include "cseries/cseries.h"
|
|
#define dot_product4d dot_product4d_inline
|
|
#include "math/real_math.h"
|
|
#undef dot_product4d
|
|
#include "game/players.h"
|
|
#include "render/render.h"
|
|
#include "render/render_debug.h"
|
|
#include "saved games/game_state.h"
|
|
#include "scenario/scenario.h"
|
|
#include "structures/structure_bsp_definitions.h"
|
|
#include "tag_files/tag_groups.h"
|
|
#include "rasterizer/rasterizer.h"
|
|
#include "structures.h"
|
|
|
|
#undef memset
|
|
#pragma intrinsic(memset)
|
|
#pragma intrinsic(abs)
|
|
|
|
/* ---------- constants */
|
|
|
|
/* ---------- macros */
|
|
|
|
#define structure_detail_object_data_get(block, index) \
|
|
TAG_BLOCK_GET_ELEMENT((block), (index), struct structure_detail_object_data)
|
|
#define detail_object_cell_definition_get(block, index) \
|
|
TAG_BLOCK_GET_ELEMENT((block), (index), struct detail_object_cell_definition)
|
|
#define detail_object_count_get(block, index) \
|
|
TAG_BLOCK_GET_ELEMENT((block), (index), word)
|
|
#define detail_object_z_reference_vector_get(block, index) \
|
|
TAG_BLOCK_GET_ELEMENT((block), (index), real_vector4d)
|
|
#define detail_object_get(block, index) \
|
|
TAG_BLOCK_GET_ELEMENT((block), (index), struct detail_object)
|
|
|
|
/* ---------- structures */
|
|
|
|
struct detail_object_cell_coordinate
|
|
{
|
|
short x;
|
|
short y;
|
|
short z;
|
|
boolean initialized;
|
|
byte pad07;
|
|
};
|
|
|
|
struct detail_object_cell_definition
|
|
{
|
|
short cell_x;
|
|
short cell_y;
|
|
short cell_z;
|
|
short offset_z;
|
|
unsigned long valid_layers;
|
|
long start_index;
|
|
long count_index;
|
|
long unused14[3];
|
|
};
|
|
|
|
struct detail_object_cell_data
|
|
{
|
|
long first_detail_object_index;
|
|
long detail_object_count;
|
|
short cell_x;
|
|
short cell_y;
|
|
real cell_z;
|
|
long first_vertex_index;
|
|
real_vector4d *z_reference_vector;
|
|
};
|
|
|
|
struct detail_object_layer_data
|
|
{
|
|
struct detail_object_cell_data *cells;
|
|
short cell_count;
|
|
short collection_definition_index;
|
|
};
|
|
|
|
struct detail_object_view_data
|
|
{
|
|
struct detail_object_layer_data *layers;
|
|
short layer_count;
|
|
word pad06;
|
|
};
|
|
|
|
struct detail_object_runtime_data
|
|
{
|
|
struct detail_object_cell_data cells[32][27];
|
|
struct detail_object_layer_data layers[32];
|
|
struct detail_object_view_data view_data;
|
|
struct detail_object_cell_coordinate cell_coordinate;
|
|
};
|
|
|
|
struct detail_object_global_runtime_data
|
|
{
|
|
struct detail_object_runtime_data local_player_data[2];
|
|
real_vector4d default_z_reference_vector;
|
|
};
|
|
|
|
struct structure_detail_object_data
|
|
{
|
|
struct tag_block cells;
|
|
struct tag_block detail_objects;
|
|
struct tag_block counts;
|
|
struct tag_block z_reference_vectors;
|
|
byte valid;
|
|
byte pad31[3];
|
|
long unused34[3];
|
|
};
|
|
|
|
struct detail_object
|
|
{
|
|
byte position[3];
|
|
byte data;
|
|
word color;
|
|
};
|
|
|
|
typedef char detail_object_cell_coordinate_size[
|
|
sizeof(struct detail_object_cell_coordinate) == 0x8 ? 1 : -1];
|
|
typedef char detail_object_cell_definition_size[
|
|
sizeof(struct detail_object_cell_definition) == 0x20 ? 1 : -1];
|
|
typedef char detail_object_cell_data_size[
|
|
sizeof(struct detail_object_cell_data) == 0x18 ? 1 : -1];
|
|
typedef char detail_object_layer_data_size[
|
|
sizeof(struct detail_object_layer_data) == 0x8 ? 1 : -1];
|
|
typedef char detail_object_view_data_size[
|
|
sizeof(struct detail_object_view_data) == 0x8 ? 1 : -1];
|
|
typedef char detail_object_runtime_data_size[
|
|
sizeof(struct detail_object_runtime_data) == 0x5210 ? 1 : -1];
|
|
typedef char detail_object_global_runtime_data_size[
|
|
sizeof(struct detail_object_global_runtime_data) == 0xA430 ? 1 : -1];
|
|
typedef char structure_detail_object_data_size[
|
|
sizeof(struct structure_detail_object_data) == 0x40 ? 1 : -1];
|
|
typedef char detail_object_size[
|
|
sizeof(struct detail_object) == 0x6 ? 1 : -1];
|
|
|
|
/* ---------- prototypes */
|
|
|
|
static real calculate_world_from_cell_index_and_offset(
|
|
real cell_index,
|
|
real offset);
|
|
static struct detail_object_runtime_data *get_local_player_datum(
|
|
short local_player_index);
|
|
static boolean key_compare_cells_lower_bound(
|
|
struct detail_object_cell_coordinate const *key,
|
|
struct detail_object_cell_definition const *cell);
|
|
static boolean key_compare_cells_upper_bound(
|
|
struct detail_object_cell_coordinate const *key,
|
|
struct detail_object_cell_definition const *cell);
|
|
static struct detail_object_cell_definition *get_lower_bound_cell(
|
|
struct detail_object_cell_definition *begin,
|
|
struct detail_object_cell_definition *end,
|
|
struct detail_object_cell_coordinate const *key);
|
|
static struct detail_object_cell_definition *get_upper_bound_cell(
|
|
struct detail_object_cell_definition *begin,
|
|
struct detail_object_cell_definition *end,
|
|
struct detail_object_cell_coordinate const *key);
|
|
|
|
/* ---------- globals */
|
|
|
|
boolean debug_detail_objects = FALSE;
|
|
|
|
static struct detail_object_global_runtime_data *detail_object_global_runtime_data = NULL;
|
|
static boolean fudge_vector = FALSE;
|
|
static real fudge_offset = 0.0f;
|
|
static real final_offset = 0.0f;
|
|
|
|
/* ---------- public code */
|
|
|
|
void structure_detail_objects_initialize(
|
|
void)
|
|
{
|
|
detail_object_global_runtime_data = game_state_malloc(
|
|
"structure detail objects",
|
|
NULL,
|
|
sizeof(*detail_object_global_runtime_data));
|
|
detail_object_global_runtime_data->default_z_reference_vector.i = 0.0f;
|
|
detail_object_global_runtime_data->default_z_reference_vector.j = 0.0f;
|
|
detail_object_global_runtime_data->default_z_reference_vector.k = 1.0f;
|
|
detail_object_global_runtime_data->default_z_reference_vector.l = 0.0f;
|
|
|
|
return;
|
|
}
|
|
|
|
void structure_detail_objects_dispose_from_old_map(
|
|
void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
void structure_detail_objects_dispose(
|
|
void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
void structure_detail_objects_flush(
|
|
void)
|
|
{
|
|
detail_object_global_runtime_data->local_player_data[0].cell_coordinate.initialized = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
void detail_object_offset(
|
|
real offset)
|
|
{
|
|
final_offset = offset;
|
|
fudge_vector = TRUE;
|
|
fudge_offset = offset - fudge_offset;
|
|
|
|
return;
|
|
}
|
|
|
|
/* ---------- private code */
|
|
|
|
static real calculate_world_from_cell_index_and_offset(
|
|
real cell_index,
|
|
real offset)
|
|
{
|
|
return (offset * (1.0f / 255.0f) + cell_index) * 8.0f;
|
|
}
|
|
|
|
static struct detail_object_runtime_data *get_local_player_datum(
|
|
short local_player_index)
|
|
{
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structure_detail_objects.c",
|
|
0x56,
|
|
local_player_index==0);
|
|
|
|
return &detail_object_global_runtime_data->local_player_data[local_player_index];
|
|
}
|
|
|
|
static boolean key_compare_cells_lower_bound(
|
|
struct detail_object_cell_coordinate const *key,
|
|
struct detail_object_cell_definition const *cell)
|
|
{
|
|
return cell->cell_x < key->x ||
|
|
(cell->cell_x == key->x &&
|
|
(cell->cell_y < key->y ||
|
|
(cell->cell_y == key->y && cell->cell_z < key->z)));
|
|
}
|
|
|
|
static boolean key_compare_cells_upper_bound(
|
|
struct detail_object_cell_coordinate const *key,
|
|
struct detail_object_cell_definition const *cell)
|
|
{
|
|
return cell->cell_x > key->x ||
|
|
(cell->cell_x == key->x &&
|
|
(cell->cell_y > key->y ||
|
|
(cell->cell_y == key->y && cell->cell_z > key->z)));
|
|
}
|
|
|
|
static struct detail_object_cell_definition *get_lower_bound_cell(
|
|
struct detail_object_cell_definition *begin,
|
|
struct detail_object_cell_definition *end,
|
|
struct detail_object_cell_coordinate const *key)
|
|
{
|
|
long count = end - begin;
|
|
|
|
while (count > 0)
|
|
{
|
|
long half = count / 2;
|
|
struct detail_object_cell_definition *middle = begin + half;
|
|
|
|
if (key_compare_cells_lower_bound(key, middle))
|
|
{
|
|
begin = middle + 1;
|
|
count -= half + 1;
|
|
}
|
|
else
|
|
{
|
|
count = half;
|
|
}
|
|
}
|
|
|
|
return begin;
|
|
}
|
|
|
|
static struct detail_object_cell_definition *get_upper_bound_cell(
|
|
struct detail_object_cell_definition *begin,
|
|
struct detail_object_cell_definition *end,
|
|
struct detail_object_cell_coordinate const *key)
|
|
{
|
|
long count = end - begin;
|
|
|
|
while (count > 0)
|
|
{
|
|
long half = count / 2;
|
|
struct detail_object_cell_definition *middle = begin + half;
|
|
|
|
if (!key_compare_cells_upper_bound(key, middle))
|
|
{
|
|
begin = middle + 1;
|
|
count -= half + 1;
|
|
}
|
|
else
|
|
{
|
|
count = half;
|
|
}
|
|
}
|
|
|
|
return begin;
|
|
}
|
|
|
|
real dot_product4d(
|
|
real_vector4d const *a,
|
|
real_vector4d const *b)
|
|
{
|
|
return a->i*b->i + a->j*b->j + a->k*b->k + a->l*b->l;
|
|
}
|
|
|
|
void structure_detail_objects_initialize_for_new_map(
|
|
void)
|
|
{
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structure_detail_objects.c",
|
|
0x6D,
|
|
detail_object_global_runtime_data);
|
|
csmemset(
|
|
detail_object_global_runtime_data,
|
|
0,
|
|
sizeof(*detail_object_global_runtime_data));
|
|
detail_object_global_runtime_data->local_player_data[0].cell_coordinate.initialized = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
void structure_render_detail_objects(
|
|
void)
|
|
{
|
|
if (local_player_count() == 1 && render.local_player_index != NONE)
|
|
{
|
|
struct structure_detail_object_data *detail_object_data =
|
|
global_structure_bsp_get()->detail_object_data.count ?
|
|
structure_detail_object_data_get(&global_structure_bsp_get()->detail_object_data, 0) :
|
|
NULL;
|
|
struct detail_object_runtime_data *local_player_data = get_local_player_datum(0);
|
|
struct detail_object_cell_coordinate camera_cell = {
|
|
(short)fast_ftol(render.camera.position.x * 0.125f - 0.5f),
|
|
(short)fast_ftol(render.camera.position.y * 0.125f - 0.5f),
|
|
(short)fast_ftol(render.camera.position.z * 0.125f - 0.5f) };
|
|
|
|
if (detail_object_data->valid)
|
|
{
|
|
rasterizer_detail_objects_begin();
|
|
|
|
if (camera_cell.x != local_player_data->cell_coordinate.x ||
|
|
camera_cell.y != local_player_data->cell_coordinate.y ||
|
|
camera_cell.z != local_player_data->cell_coordinate.z ||
|
|
!local_player_data->cell_coordinate.initialized ||
|
|
TEST_FLAG(detail_object_data->valid, 1))
|
|
{
|
|
unsigned long visible_layer_flags = 0;
|
|
short layer_cell_counts[32] = { 0 };
|
|
short x_delta;
|
|
short y_delta;
|
|
|
|
detail_object_data->valid = TRUE;
|
|
local_player_data->cell_coordinate = camera_cell;
|
|
local_player_data->cell_coordinate.initialized = TRUE;
|
|
|
|
for (x_delta = -1; x_delta <= 1; x_delta++)
|
|
{
|
|
for (y_delta = -1; y_delta <= 1; y_delta++)
|
|
{
|
|
struct detail_object_cell_definition *begin =
|
|
detail_object_cell_definition_get(&detail_object_data->cells, 0);
|
|
struct detail_object_cell_definition *end = detail_object_cell_definition_get(
|
|
&detail_object_data->cells,
|
|
detail_object_data->cells.count - 1) + 1;
|
|
struct detail_object_cell_coordinate key = {
|
|
(short)(camera_cell.x - x_delta),
|
|
(short)(camera_cell.y - y_delta),
|
|
camera_cell.z };
|
|
struct detail_object_cell_definition *lower_bound_cell;
|
|
struct detail_object_cell_definition *upper_bound_cell;
|
|
|
|
key.z--;
|
|
lower_bound_cell = get_lower_bound_cell(begin, end, &key);
|
|
key.z += 3;
|
|
upper_bound_cell = get_upper_bound_cell(begin, end, &key) - 1;
|
|
key.z = camera_cell.z;
|
|
|
|
if (lower_bound_cell->cell_x == key.x &&
|
|
lower_bound_cell->cell_y == key.y &&
|
|
upper_bound_cell->cell_x == key.x &&
|
|
upper_bound_cell->cell_y == key.y)
|
|
{
|
|
struct detail_object_cell_definition *cell;
|
|
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\structures\\structure_detail_objects.c",
|
|
0xC6,
|
|
lower_bound_cell<=upper_bound_cell);
|
|
|
|
upper_bound_cell++;
|
|
for (cell = lower_bound_cell; cell < upper_bound_cell; cell++)
|
|
{
|
|
if (abs(camera_cell.z - cell->cell_z) <= 1)
|
|
{
|
|
long first_detail_object_index = 0;
|
|
short count_index = 0;
|
|
short layer_index;
|
|
|
|
visible_layer_flags |= cell->valid_layers;
|
|
for (layer_index = 0; layer_index < 32; layer_index++)
|
|
{
|
|
if (TEST_FLAG(cell->valid_layers, layer_index))
|
|
{
|
|
struct detail_object_cell_data *cell_data =
|
|
&local_player_data->cells[layer_index][layer_cell_counts[layer_index]++];
|
|
|
|
cell_data->cell_x = cell->cell_x;
|
|
cell_data->cell_y = cell->cell_y;
|
|
cell_data->cell_z =
|
|
(real)cell->offset_z * (1.0f / 255.0f) + (real)cell->cell_z;
|
|
cell_data->first_detail_object_index =
|
|
cell->start_index + first_detail_object_index;
|
|
cell_data->detail_object_count = *detail_object_count_get(
|
|
&detail_object_data->counts,
|
|
cell->count_index + count_index);
|
|
cell_data->z_reference_vector = detail_object_data->z_reference_vectors.count ?
|
|
detail_object_z_reference_vector_get(
|
|
&detail_object_data->z_reference_vectors,
|
|
cell->count_index + count_index) :
|
|
&detail_object_global_runtime_data->default_z_reference_vector;
|
|
|
|
first_detail_object_index += cell_data->detail_object_count;
|
|
count_index++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
short render_layer_index = 0;
|
|
short layer_index;
|
|
|
|
local_player_data->view_data.layers = local_player_data->layers;
|
|
local_player_data->view_data.layer_count = 0;
|
|
for (layer_index = 0; layer_index < 32; layer_index++)
|
|
{
|
|
if (TEST_FLAG(visible_layer_flags, layer_index) && layer_cell_counts[layer_index])
|
|
{
|
|
struct detail_object_layer_data *layer =
|
|
&local_player_data->layers[render_layer_index++];
|
|
|
|
layer->cells = local_player_data->cells[layer_index];
|
|
layer->cell_count = layer_cell_counts[layer_index];
|
|
layer->collection_definition_index = layer_index;
|
|
local_player_data->view_data.layer_count++;
|
|
}
|
|
}
|
|
|
|
rasterizer_detail_objects_rebuild_vertices(
|
|
&local_player_data->view_data);
|
|
}
|
|
}
|
|
|
|
rasterizer_detail_objects_draw(&local_player_data->view_data);
|
|
rasterizer_detail_objects_end();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void render_debug_detail_objects(
|
|
void)
|
|
{
|
|
if (local_player_count() == 1 &&
|
|
render.local_player_index != NONE &&
|
|
debug_detail_objects)
|
|
{
|
|
struct structure_detail_object_data *detail_object_data;
|
|
struct detail_object_runtime_data *local_player_data;
|
|
|
|
if (global_structure_bsp_get()->detail_object_data.count)
|
|
{
|
|
detail_object_data = structure_detail_object_data_get(
|
|
&global_structure_bsp_get()->detail_object_data,
|
|
0);
|
|
}
|
|
else
|
|
{
|
|
detail_object_data = NULL;
|
|
}
|
|
|
|
local_player_data = get_local_player_datum(0);
|
|
if (debug_detail_objects)
|
|
{
|
|
struct detail_object_view_data *view_data = &get_local_player_datum(0)->view_data;
|
|
short layer_index;
|
|
|
|
for (layer_index = 0; layer_index < view_data->layer_count; layer_index++)
|
|
{
|
|
struct detail_object_layer_data *layer = &local_player_data->layers[layer_index];
|
|
short cell_index;
|
|
|
|
for (cell_index = 0; cell_index < layer->cell_count; cell_index++)
|
|
{
|
|
struct detail_object_cell_data *cell = &layer->cells[cell_index];
|
|
boolean clipped = FALSE;
|
|
long detail_object_index;
|
|
|
|
if (fudge_vector)
|
|
{
|
|
cell->z_reference_vector->l +=
|
|
fudge_offset * 0.125f;
|
|
}
|
|
for (detail_object_index = 0;
|
|
detail_object_index < cell->detail_object_count;
|
|
detail_object_index++)
|
|
{
|
|
struct detail_object *detail_object = detail_object_get(
|
|
&detail_object_data->detail_objects,
|
|
cell->first_detail_object_index + detail_object_index);
|
|
real_vector3d detail_object_position;
|
|
real_point3d position;
|
|
|
|
detail_object_position.i = (real)detail_object->position[0];
|
|
detail_object_position.j = (real)detail_object->position[1];
|
|
detail_object_position.k = (real)detail_object->position[2];
|
|
|
|
position.x = calculate_world_from_cell_index_and_offset(
|
|
(real)cell->cell_x,
|
|
(real)detail_object->position[0]);
|
|
position.y = calculate_world_from_cell_index_and_offset(
|
|
(real)cell->cell_y,
|
|
(real)detail_object->position[1]);
|
|
position.z =
|
|
((detail_object_position.i * cell->z_reference_vector->i +
|
|
detail_object_position.j * cell->z_reference_vector->j +
|
|
detail_object_position.k * cell->z_reference_vector->k) *
|
|
(1.0f / 255.0f) + cell->z_reference_vector->l +
|
|
cell->cell_z) * 8.0f;
|
|
|
|
if (position.z > (cell->cell_z + 1.0f) * 8.0f ||
|
|
position.z < cell->cell_z * 8.0f)
|
|
{
|
|
clipped = TRUE;
|
|
}
|
|
|
|
render_debug_point(
|
|
TRUE,
|
|
&position,
|
|
0.1f,
|
|
global_real_argb_red);
|
|
}
|
|
|
|
{
|
|
real_rectangle3d bounds = {
|
|
(real)(cell->cell_x * 8),
|
|
(real)(cell->cell_x * 8 + 8),
|
|
(real)(cell->cell_y * 8),
|
|
(real)(cell->cell_y * 8 + 8),
|
|
cell->cell_z * 8.0f,
|
|
(cell->cell_z + 1.0f) * 8.0f };
|
|
|
|
render_debug_box_outline(TRUE, &bounds, global_real_argb_blue);
|
|
|
|
if (clipped)
|
|
{
|
|
real_argb_color clipped_color = *global_real_argb_grey;
|
|
|
|
clipped_color.alpha = 0.3f;
|
|
render_debug_box_outline(TRUE, &bounds, &clipped_color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fudge_vector = FALSE;
|
|
fudge_offset = final_offset;
|
|
}
|
|
|
|
return;
|
|
}
|