Move morph_data into dynamic allocations
This improves poison detection, and eliminates some large static allocations (MAX_VECS * ((2 * vms_vector) + fix)).
This commit is contained in:
parent
c55c7d1bd6
commit
cac5f1da56
|
@ -36,6 +36,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
||||||
|
|
||||||
#ifdef dsx
|
#ifdef dsx
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace dcx {
|
namespace dcx {
|
||||||
|
|
||||||
|
@ -51,11 +52,11 @@ struct morph_data : prohibit_void_ptr<morph_data>
|
||||||
animating,
|
animating,
|
||||||
visible,
|
visible,
|
||||||
};
|
};
|
||||||
object_base *obj = nullptr; // object which is morphing
|
object_base *const obj; // object which is morphing
|
||||||
uint8_t n_submodels_active;
|
const object_signature_t Morph_sig;
|
||||||
uint8_t morph_save_control_type;
|
uint8_t morph_save_control_type;
|
||||||
uint8_t morph_save_movement_type;
|
uint8_t morph_save_movement_type;
|
||||||
object_signature_t Morph_sig;
|
uint8_t n_submodels_active;
|
||||||
physics_info morph_save_phys_info;
|
physics_info morph_save_phys_info;
|
||||||
array<submodel_state, MAX_SUBMODELS> submodel_active; // which submodels are active
|
array<submodel_state, MAX_SUBMODELS> submodel_active; // which submodels are active
|
||||||
array<vms_vector, MAX_VECS> morph_vecs, morph_deltas;
|
array<vms_vector, MAX_VECS> morph_vecs, morph_deltas;
|
||||||
|
@ -63,14 +64,20 @@ struct morph_data : prohibit_void_ptr<morph_data>
|
||||||
array<int, MAX_SUBMODELS>
|
array<int, MAX_SUBMODELS>
|
||||||
n_morphing_points, // how many active points in each part
|
n_morphing_points, // how many active points in each part
|
||||||
submodel_startpoints; // first point for each submodel
|
submodel_startpoints; // first point for each submodel
|
||||||
|
explicit morph_data(object_base &o) :
|
||||||
|
obj(&o), Morph_sig(o.signature)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct d_level_unique_morph_object_state
|
struct d_level_unique_morph_object_state
|
||||||
{
|
{
|
||||||
array<morph_data, 5> morph_objects;
|
array<std::unique_ptr<morph_data>, 5> morph_objects;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern d_level_unique_morph_object_state LevelUniqueMorphObjectState;
|
extern d_level_unique_morph_object_state LevelUniqueMorphObjectState;
|
||||||
|
|
||||||
|
std::unique_ptr<morph_data> *find_morph_data(object_base &obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void morph_start(vmobjptr_t obj);
|
void morph_start(vmobjptr_t obj);
|
||||||
|
@ -80,8 +87,6 @@ void do_morph_frame(object &obj);
|
||||||
|
|
||||||
//called at the start of a level
|
//called at the start of a level
|
||||||
void init_morphs();
|
void init_morphs();
|
||||||
|
|
||||||
morph_data *find_morph_data(object &obj);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,23 +52,23 @@ namespace dcx {
|
||||||
|
|
||||||
d_level_unique_morph_object_state LevelUniqueMorphObjectState;
|
d_level_unique_morph_object_state LevelUniqueMorphObjectState;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//returns ptr to data for this object, or NULL if none
|
//returns ptr to data for this object, or NULL if none
|
||||||
morph_data *find_morph_data(object &obj)
|
std::unique_ptr<morph_data> *find_morph_data(object_base &obj)
|
||||||
{
|
{
|
||||||
auto &morph_objects = LevelUniqueMorphObjectState.morph_objects;
|
auto &morph_objects = LevelUniqueMorphObjectState.morph_objects;
|
||||||
if (Newdemo_state == ND_STATE_PLAYBACK) {
|
if (Newdemo_state == ND_STATE_PLAYBACK) {
|
||||||
morph_objects[0].obj = &obj;
|
morph_objects[0] = make_unique<morph_data>(obj);
|
||||||
return &morph_objects[0];
|
return &morph_objects[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
range_for (auto &i, morph_objects)
|
range_for (auto &i, morph_objects)
|
||||||
if (i.obj == &obj)
|
if (i && i->obj == &obj)
|
||||||
return &i;
|
return &i;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void assign_max(fix &a, const fix &b)
|
static void assign_max(fix &a, const fix &b)
|
||||||
{
|
{
|
||||||
a = std::max(a, b);
|
a = std::max(a, b);
|
||||||
|
@ -214,14 +214,13 @@ static void update_points(const polymodel *const pm, const unsigned submodel_num
|
||||||
//process the morphing object for one frame
|
//process the morphing object for one frame
|
||||||
void do_morph_frame(object &obj)
|
void do_morph_frame(object &obj)
|
||||||
{
|
{
|
||||||
morph_data *md;
|
const auto umd = find_morph_data(obj);
|
||||||
|
|
||||||
md = find_morph_data(obj);
|
if (!umd) { //maybe loaded half-morphed from disk
|
||||||
|
|
||||||
if (md == NULL) { //maybe loaded half-morphed from disk
|
|
||||||
obj.flags |= OF_SHOULD_BE_DEAD; //..so kill it
|
obj.flags |= OF_SHOULD_BE_DEAD; //..so kill it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto md = umd->get();
|
||||||
assert(md->obj == &obj);
|
assert(md->obj == &obj);
|
||||||
|
|
||||||
auto &Polygon_models = LevelSharedPolygonModelState.Polygon_models;
|
auto &Polygon_models = LevelSharedPolygonModelState.Polygon_models;
|
||||||
|
@ -252,7 +251,7 @@ void do_morph_frame(object &obj)
|
||||||
obj.render_type = RT_POLYOBJ;
|
obj.render_type = RT_POLYOBJ;
|
||||||
|
|
||||||
obj.mtype.phys_info = md->morph_save_phys_info;
|
obj.mtype.phys_info = md->morph_save_phys_info;
|
||||||
md->obj = NULL;
|
umd->reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,8 +260,7 @@ constexpr vms_vector morph_rotvel{0x4000,0x2000,0x1000};
|
||||||
void init_morphs()
|
void init_morphs()
|
||||||
{
|
{
|
||||||
auto &morph_objects = LevelUniqueMorphObjectState.morph_objects;
|
auto &morph_objects = LevelUniqueMorphObjectState.morph_objects;
|
||||||
range_for (auto &i, morph_objects)
|
morph_objects = {};
|
||||||
i.obj = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,21 +274,22 @@ void morph_start(const vmobjptr_t obj)
|
||||||
auto &morph_objects = LevelUniqueMorphObjectState.morph_objects;
|
auto &morph_objects = LevelUniqueMorphObjectState.morph_objects;
|
||||||
const auto mob = morph_objects.begin();
|
const auto mob = morph_objects.begin();
|
||||||
const auto moe = morph_objects.end();
|
const auto moe = morph_objects.end();
|
||||||
const auto mop = [](const morph_data &mo) {
|
const auto mop = [](const std::unique_ptr<morph_data> &pmo) {
|
||||||
return mo.obj == nullptr || mo.obj->type == OBJ_NONE || mo.obj->signature != mo.Morph_sig;
|
if (!pmo)
|
||||||
|
return true;
|
||||||
|
auto &mo = *pmo.get();
|
||||||
|
return mo.obj->type == OBJ_NONE || mo.obj->signature != mo.Morph_sig;
|
||||||
};
|
};
|
||||||
const auto moi = std::find_if(mob, moe, mop);
|
const auto moi = std::find_if(mob, moe, mop);
|
||||||
|
|
||||||
if (moi == moe) //no free slots
|
if (moi == moe) //no free slots
|
||||||
return;
|
return;
|
||||||
|
|
||||||
morph_data *const md = &*moi;
|
*moi = make_unique<morph_data>(obj);
|
||||||
|
morph_data *const md = moi->get();
|
||||||
|
|
||||||
Assert(obj->render_type == RT_POLYOBJ);
|
Assert(obj->render_type == RT_POLYOBJ);
|
||||||
|
|
||||||
md->obj = obj;
|
|
||||||
md->Morph_sig = obj->signature;
|
|
||||||
|
|
||||||
md->morph_save_control_type = obj->control_type;
|
md->morph_save_control_type = obj->control_type;
|
||||||
md->morph_save_movement_type = obj->movement_type;
|
md->morph_save_movement_type = obj->movement_type;
|
||||||
md->morph_save_phys_info = obj->mtype.phys_info;
|
md->morph_save_phys_info = obj->mtype.phys_info;
|
||||||
|
@ -391,10 +390,11 @@ void draw_morph_object(grs_canvas &canvas, const d_level_unique_light_state &Lev
|
||||||
{
|
{
|
||||||
// int save_light;
|
// int save_light;
|
||||||
polymodel *po;
|
polymodel *po;
|
||||||
morph_data *md;
|
|
||||||
|
|
||||||
md = find_morph_data(obj);
|
const auto umd = find_morph_data(obj);
|
||||||
Assert(md != NULL);
|
if (!umd)
|
||||||
|
throw std::runtime_error("missing morph data");
|
||||||
|
const auto md = umd->get();
|
||||||
|
|
||||||
auto &Polygon_models = LevelSharedPolygonModelState.Polygon_models;
|
auto &Polygon_models = LevelSharedPolygonModelState.Polygon_models;
|
||||||
po=&Polygon_models[obj->rtype.pobj_info.model_num];
|
po=&Polygon_models[obj->rtype.pobj_info.model_num];
|
||||||
|
|
|
@ -1120,14 +1120,14 @@ int state_save_all_sub(const char *filename, const char *desc)
|
||||||
{
|
{
|
||||||
if (objp->type != OBJ_NONE && objp->render_type == RT_MORPH)
|
if (objp->type != OBJ_NONE && objp->render_type == RT_MORPH)
|
||||||
{
|
{
|
||||||
morph_data *md;
|
if (const auto umd = find_morph_data(objp))
|
||||||
md = find_morph_data(objp);
|
{
|
||||||
if (md) {
|
const auto md = umd->get();
|
||||||
md->obj->control_type = md->morph_save_control_type;
|
md->obj->control_type = md->morph_save_control_type;
|
||||||
set_object_movement_type(*md->obj, md->morph_save_movement_type);
|
set_object_movement_type(*md->obj, md->morph_save_movement_type);
|
||||||
md->obj->render_type = RT_POLYOBJ;
|
md->obj->render_type = RT_POLYOBJ;
|
||||||
md->obj->mtype.phys_info = md->morph_save_phys_info;
|
md->obj->mtype.phys_info = md->morph_save_phys_info;
|
||||||
md->obj = NULL;
|
umd->reset();
|
||||||
} else { //maybe loaded half-morphed from disk
|
} else { //maybe loaded half-morphed from disk
|
||||||
objp->flags |= OF_SHOULD_BE_DEAD;
|
objp->flags |= OF_SHOULD_BE_DEAD;
|
||||||
objp->render_type = RT_POLYOBJ;
|
objp->render_type = RT_POLYOBJ;
|
||||||
|
|
Loading…
Reference in a new issue