Files
Cesarus85--ringfall-mjolnir-vr/source/math/integer_math.c
T
Berthalamewandpunpckhdq eb93ce635e wip objects.c work (#12)
* wip objects.c work

* objects_disconnect_from_structure_bsp

* match more functions

* more objects work

* objects_update work

- 93.42% matching

* match matrix4x3_transform_point

* more objects work

- fix duplicate symbol name at 1870800

* match object_choose_random_change_colors

* match object_update

* objects_garbage_collection work

* match object_set_position

* more object work

* match objects_update

* more object work

* match object_select_random_region_permutations_by_variant

* objects_in_sphere work

99.90% match

* object name list calls

* match objects_in_sphere

* misc matches

* match structure_bsp_definitions object

* match objects_in_clusters_by_indices

* more object work

* match `edit_text_handle_key`

* mark edit_text as matching

* misc changes

- match get_next_character
- match data section in objects.c

* object_export_function_values work

* match object_compute_function_values

* match object_get_orientation

* added functions and adjust formatting

* fix profile macros

* formatting changes

* more formatting

* more formatting

---------

Co-authored-by: punpckhdq <121350336+punpckhdq@users.noreply.github.com>
2026-02-15 01:05:45 +00:00

422 lines
7.3 KiB
C

/*
INTEGER_MATH.C
*/
/* ---------- headers */
#include "cseries.h"
#include "integer_math.h"
/* ---------- constants */
/* ---------- macros */
/* ---------- structures */
/* ---------- prototypes */
/* ---------- globals */
static point2d integer_origin2d= {{ 0, 0 }};
short direction_delta_x[9]= {1, 1, -1, -1, 0, 1, 0, -1, 0};
short direction_delta_y[9]= {1, -1, -1, 1, 1, 0, -1, 0, 0};
short reversed_directions[9]= {2, 3, 0, 1, 6, 7, 4, 5, 8};
point2d *global_integer_origin2d= &integer_origin2d;
/* ---------- public code */
rectangle2d *set_rectangle2d(
rectangle2d *rectangle,
short x0,
short y0,
short x1,
short y1)
{
rectangle->x0= x0;
rectangle->y0= y0;
rectangle->x1= x1;
rectangle->y1= y1;
return rectangle;
}
point2d *set_point2d(
point2d *point,
short x,
short y)
{
point->n[0]= x;
point->n[1]= y;
return point;
}
point2d *offset_point2d(
point2d *point,
short dx,
short dy)
{
point->n[0]+= dx;
point->n[1]+= dy;
return point;
}
short rectangle2d_width(
const rectangle2d *rect)
{
return rect->x1 - rect->x0;
}
short rectangle2d_height(
const rectangle2d *rect)
{
return rect->y1 - rect->y0;
}
rectangle2d *inset_rectangle2d(
rectangle2d *rectangle,
short dx,
short dy)
{
rectangle->x0+= dx;
rectangle->x1-= dx;
rectangle->y0+= dy;
rectangle->y1-= dy;
return rectangle;
}
rectangle2d *offset_rectangle2d(
rectangle2d *rectangle,
short dx,
short dy)
{
rectangle->x0+= dx;
rectangle->x1+= dx;
rectangle->y0+= dy;
rectangle->y1+= dy;
return rectangle;
}
rectangle2d* adjust_rectangle2d(
rectangle2d const *bounds,
rectangle2d const *source,
rectangle2d *destination,
short mode)
{
rectangle2d new_rectangle;
short adjust_height, adjust_width;
short bounds_width= rectangle2d_width(bounds);
short bounds_height= rectangle2d_height(bounds);
short source_width= rectangle2d_width(source);
short source_height= rectangle2d_height(source);
new_rectangle= *source;
switch (mode)
{
case _adjust_rectangle_center:
adjust_height= bounds->y0 + bounds_height/2 - source_height/2 - source->y0;
adjust_width= bounds->x0 + bounds_width/2 - source_width/2 - source->x0;
new_rectangle.x0+= adjust_width;
new_rectangle.x1+= adjust_width;
new_rectangle.y0+= adjust_height;
new_rectangle.y1+= adjust_height;
break;
case _adjust_rectangle_alert:
adjust_height= (bounds_height - source_height)/3 - source->y0 + bounds->y0;
adjust_width= (bounds_width - source_width)/2 - source->x0 + bounds->x0;
new_rectangle.x0+= adjust_width;
new_rectangle.x1+= adjust_width;
new_rectangle.y0+= adjust_height;
new_rectangle.y1+= adjust_height;
break;
default:
match_vwarn(
"c:\\halo\\SOURCE\\math\\integer_math.c",
173,
FALSE,
csprintf(temporary, "adjust_rectangle2d() can't handle mode #%d", mode)
);
break;
}
*destination= new_rectangle;
return destination;
}
boolean intersect_rectangles2d(
const rectangle2d *r1,
const rectangle2d *r2,
rectangle2d *intersection)
{
boolean result= FALSE;
rectangle2d new_rectangle;
new_rectangle.x0= MAX(r1->x0, r2->x0);
new_rectangle.x1= MIN(r1->x1, r2->x1);
new_rectangle.y0= MAX(r1->y0, r2->y0);
new_rectangle.y1= MIN(r1->y1, r2->y1);
if (new_rectangle.x0 >= new_rectangle.x1 || new_rectangle.y0 >= new_rectangle.y1)
{
memset(intersection, 0, sizeof(new_rectangle));
}
else
{
*intersection= new_rectangle;
result= TRUE;
}
return result;
}
rectangle2d *rectangle2d_hull_from_rectangles2d(
rectangle2d const *r1,
rectangle2d const *r2,
rectangle2d *hull)
{
hull->x0= MIN(r1->x0, r2->x0);
hull->x1= MAX(r1->x1, r2->x1);
hull->y0= MIN(r1->y0, r2->y0);
hull->y1= MAX(r1->y1, r2->y1);
return hull;
}
boolean point2d_in_rectangle2d(
const rectangle2d *rectangle,
const point2d *point)
{
boolean result= FALSE;
if (point->x>=rectangle->x0 && point->x<rectangle->x1)
{
if (point->y>=rectangle->y0 && point->y<rectangle->y1)
{
result= TRUE;
}
}
return result;
}
boolean interior_rectangle2d(
const rectangle2d *outer,
const rectangle2d *inner)
{
return inner->x0>=outer->x0 && inner->x1<=outer->x1 && inner->y0>=outer->y0 && inner->y1<=outer->y1;
}
boolean equal_rectangle2d(
const rectangle2d *r1,
const rectangle2d *r2)
{
return r1->x0==r2->x0 && r1->x1==r2->x1 && r1->y0==r2->y0 && r1->y1==r2->y1;
}
boolean equal_point2d(
const point2d *p1,
const point2d *p2)
{
return p1->x==p2->x && p1->y==p2->y;
}
short floor_log2(
unsigned long k)
{
unsigned long counter= k;
long result= 0;
if (k > 0)
{
for (; counter!=1; result++)
{
counter>>= 1;
}
}
return result;
}
short ceiling_log2(
unsigned long k)
{
unsigned long counter;
long result= 0;
if (k > 0)
{
counter= k - 1;
for (; counter != 1; result++)
{
counter >>= 1;
}
}
return result + 1;
}
unsigned long floor_power2(
word x)
{
long result= 1;
while (result*2<= x)
{
result*= 2;
}
return result;
}
unsigned long ceiling_power2(
word x)
{
long result= 1;
while (result < x)
{
result<<= 1;
}
return result;
}
unsigned long integer_square_root(
unsigned long k)
{
unsigned long sum;
unsigned long result= 0;
unsigned long magic= 0x40000000;
do
{
sum= magic + result;
if (magic + result <= k)
{
k -= sum;
result= sum + magic;
}
magic>>= 2;
result>>= 1;
}
while (magic);
if (k>result)
{
result++;
}
return result;
}
boolean bit_vector_and(
short count,
unsigned long const *v0,
unsigned long const *v1,
unsigned long *result)
{
short i;
boolean res= FALSE;
match_assert("c:\\halo\\SOURCE\\math\\integer_math.c", 348, v0 && v1);
for (i= (BIT_VECTOR_SIZE_IN_LONGS(count))-1; i>= 0; i--)
{
long and_result= v0[i] & v1[i];
if (result)
{
result[i]= and_result;
}
if (and_result)
{
res= TRUE;
}
}
return res;
}
void bit_vector_or(
short count,
const unsigned long *v0,
const unsigned long *v1,
unsigned long *result)
{
short i;
match_assert("c:\\halo\\SOURCE\\math\\integer_math.c", 369, v0 && v1);
match_assert("c:\\halo\\SOURCE\\math\\integer_math.c", 370, result);
for (i= BIT_VECTOR_SIZE_IN_LONGS(count) - 1; i>= 0; i--)
{
result[i]= v0[i] | v1[i];
}
return;
}
void bit_vector_not(
short count,
const unsigned long *vector,
unsigned long *result)
{
short i;
match_assert("c:\\halo\\SOURCE\\math\\integer_math.c", 387, vector && result);
for (i= BIT_VECTOR_SIZE_IN_LONGS(count) - 1; i>= 0; i--)
{
result[i]= ~vector[i];
}
return;
}
rectangle2d *scale_rectangle2d(
const rectangle2d *bounds,
const rectangle2d *source,
rectangle2d *destination,
short scale)
{
rectangle2d new_rectangle;
short new_height;
short new_width;
short bounds_width= rectangle2d_width(bounds);
short bounds_height= rectangle2d_height(bounds);
short source_width= rectangle2d_width(source);
short source_height= rectangle2d_height(source);
if (bounds_height*source_width > source_height*bounds_width)
{
new_width= bounds_width;
new_height= source_height*bounds_width/source_width;
}
else
{
new_height= bounds_height;
new_width= bounds_height*source_width/source_height;
}
new_width= SHORT_FIXED_TO_LONG(new_width*scale);
new_height= SHORT_FIXED_TO_LONG(new_height*scale);
set_rectangle2d(&new_rectangle, 0, 0, new_width, new_height);
offset_rectangle2d(
&new_rectangle,
bounds->x0 + (bounds_width - new_width) / 2,
bounds->y0 + (bounds_height - new_height) / 2
);
*destination= new_rectangle;
return destination;
}
/* ---------- private code */