Use bitmask for hitobj_list
Reduces sizeof(laser_info) from 392 to 80.
This commit is contained in:
parent
510fe02825
commit
d7d052857a
|
@ -36,6 +36,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
|||
#include "dxxsconf.h"
|
||||
#include "compiler-array.h"
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
/*
|
||||
* CONSTANTS
|
||||
|
@ -223,12 +224,71 @@ struct physics_info_rw
|
|||
|
||||
struct laser_info
|
||||
{
|
||||
struct hitobj_list_t
|
||||
{
|
||||
typedef unsigned objnum_t;
|
||||
template <typename T>
|
||||
struct tproxy
|
||||
{
|
||||
T *addr;
|
||||
uint8_t mask;
|
||||
tproxy(T *a, uint8_t m) :
|
||||
addr(a), mask(m)
|
||||
{
|
||||
assert(m);
|
||||
assert(!(m & (m - 1)));
|
||||
}
|
||||
dxx_explicit_operator_bool operator bool() const
|
||||
{
|
||||
return *addr & mask;
|
||||
}
|
||||
};
|
||||
typedef tproxy<const uint8_t> cproxy;
|
||||
struct proxy : public tproxy<uint8_t>
|
||||
{
|
||||
proxy(uint8_t *a, uint8_t m) :
|
||||
tproxy<uint8_t>(a, m)
|
||||
{
|
||||
}
|
||||
proxy &operator=(bool b)
|
||||
{
|
||||
if (b)
|
||||
*addr |= mask;
|
||||
else
|
||||
*addr &= ~mask;
|
||||
return *this;
|
||||
}
|
||||
template <typename T>
|
||||
void operator=(T) DXX_CXX11_EXPLICIT_DELETE;
|
||||
};
|
||||
array<uint8_t, (MAX_OBJECTS + 7) / 8> mask;
|
||||
proxy operator[](objnum_t i)
|
||||
{
|
||||
return make_proxy<proxy>(mask, i);
|
||||
}
|
||||
cproxy operator[](objnum_t i) const
|
||||
{
|
||||
return make_proxy<cproxy>(mask, i);
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
mask.fill(0);
|
||||
}
|
||||
template <typename T1, typename T2>
|
||||
static T1 make_proxy(T2 &mask, objnum_t i)
|
||||
{
|
||||
typename T2::size_type index = i / 8, bitshift = i % 8;
|
||||
if (!(index < mask.size()))
|
||||
throw std::out_of_range("index exceeds object range");
|
||||
return T1(&mask[index], 1 << bitshift);
|
||||
}
|
||||
};
|
||||
short parent_type; // The type of the parent of this object
|
||||
short parent_num; // The object's parent's number
|
||||
int parent_signature; // The object's parent's signature...
|
||||
fix64 creation_time; // Absolute time of creation.
|
||||
hitobj_list_t hitobj_list; // list of all objects persistent weapon has already damaged (useful in case it's in contact with two objects at the same time)
|
||||
short last_hitobj; // For persistent weapons (survive object collision), object it most recently hit.
|
||||
ubyte hitobj_list[MAX_OBJECTS]; // list of all objects persistent weapon has already damaged (useful in case it's in contact with two objects at the same time)
|
||||
short track_goal; // Object this object is tracking.
|
||||
fix multiplier; // Power if this is a fusion bolt (or other super weapon to be added).
|
||||
fix track_turn_time;
|
||||
|
|
|
@ -1275,7 +1275,7 @@ static void collide_weapon_and_controlcen( object * weapon, object *controlcen,
|
|||
damage = weapon->shields*2; // to not alter Gameplay too much, multiply damage by 2.
|
||||
if (!weapon->ctype.laser_info.hitobj_list[controlcen-Objects])
|
||||
{
|
||||
weapon->ctype.laser_info.hitobj_list[controlcen-Objects] = 1;
|
||||
weapon->ctype.laser_info.hitobj_list[controlcen-Objects] = true;
|
||||
weapon->ctype.laser_info.last_hitobj = controlcen-Objects;
|
||||
}
|
||||
else
|
||||
|
@ -1655,7 +1655,7 @@ static void collide_robot_and_weapon( object * robot, object * weapon, vms_vecto
|
|||
{
|
||||
if (!weapon->ctype.laser_info.hitobj_list[robot-Objects])
|
||||
{
|
||||
weapon->ctype.laser_info.hitobj_list[robot-Objects] = 1;
|
||||
weapon->ctype.laser_info.hitobj_list[robot-Objects] = true;
|
||||
weapon->ctype.laser_info.last_hitobj = robot-Objects;
|
||||
}
|
||||
else
|
||||
|
@ -2204,7 +2204,7 @@ void collide_player_and_weapon( object * playerobj, object * weapon, vms_vector
|
|||
{
|
||||
if (!weapon->ctype.laser_info.hitobj_list[playerobj-Objects])
|
||||
{
|
||||
weapon->ctype.laser_info.hitobj_list[playerobj-Objects] = 1;
|
||||
weapon->ctype.laser_info.hitobj_list[playerobj-Objects] = true;
|
||||
weapon->ctype.laser_info.last_hitobj = playerobj-Objects;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1208,7 +1208,7 @@ int obj_create(enum object_type_t type, ubyte id,int segnum,const vms_vector *po
|
|||
obj->mtype.phys_info.flags |= (Weapon_info[get_weapon_id(obj)].persistent*PF_PERSISTENT);
|
||||
obj->ctype.laser_info.creation_time = GameTime64;
|
||||
obj->ctype.laser_info.last_hitobj = -1;
|
||||
memset(&obj->ctype.laser_info.hitobj_list, 0, sizeof(ubyte)*MAX_OBJECTS);
|
||||
obj->ctype.laser_info.hitobj_list.clear();
|
||||
obj->ctype.laser_info.multiplier = F1_0;
|
||||
#if defined(DXX_BUILD_DESCENT_II)
|
||||
obj->ctype.laser_info.last_afterburner_time = 0;
|
||||
|
|
|
@ -349,7 +349,7 @@ static void state_object_rw_to_object(object_rw *obj_rw, object *obj)
|
|||
obj->ctype.laser_info.parent_signature = obj_rw->ctype.laser_info.parent_signature;
|
||||
obj->ctype.laser_info.creation_time = obj_rw->ctype.laser_info.creation_time;
|
||||
obj->ctype.laser_info.last_hitobj = obj_rw->ctype.laser_info.last_hitobj;
|
||||
obj->ctype.laser_info.hitobj_list[obj->ctype.laser_info.last_hitobj] = 1; // restore most recent hitobj to hitobj_list
|
||||
obj->ctype.laser_info.hitobj_list[obj->ctype.laser_info.last_hitobj] = true; // restore most recent hitobj to hitobj_list
|
||||
obj->ctype.laser_info.track_goal = obj_rw->ctype.laser_info.track_goal;
|
||||
obj->ctype.laser_info.multiplier = obj_rw->ctype.laser_info.multiplier;
|
||||
obj->ctype.laser_info.track_turn_time = HOMING_TURN_TIME;
|
||||
|
|
Loading…
Reference in a new issue