Use bitmask for hitobj_list

Reduces sizeof(laser_info) from 392 to 80.
This commit is contained in:
Kp 2013-12-26 03:10:16 +00:00
parent 510fe02825
commit d7d052857a
4 changed files with 66 additions and 6 deletions

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;