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
|
||||
#include "object.h"
|
||||
#include <memory>
|
||||
|
||||
namespace dcx {
|
||||
|
||||
|
@ -51,11 +52,11 @@ struct morph_data : prohibit_void_ptr<morph_data>
|
|||
animating,
|
||||
visible,
|
||||
};
|
||||
object_base *obj = nullptr; // object which is morphing
|
||||
uint8_t n_submodels_active;
|
||||
object_base *const obj; // object which is morphing
|
||||
const object_signature_t Morph_sig;
|
||||
uint8_t morph_save_control_type;
|
||||
uint8_t morph_save_movement_type;
|
||||
object_signature_t Morph_sig;
|
||||
uint8_t n_submodels_active;
|
||||
physics_info morph_save_phys_info;
|
||||
array<submodel_state, MAX_SUBMODELS> submodel_active; // which submodels are active
|
||||
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>
|
||||
n_morphing_points, // how many active points in each part
|
||||
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
|
||||
{
|
||||
array<morph_data, 5> morph_objects;
|
||||
array<std::unique_ptr<morph_data>, 5> morph_objects;
|
||||
};
|
||||
|
||||
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);
|
||||
|
@ -80,8 +87,6 @@ void do_morph_frame(object &obj);
|
|||
|
||||
//called at the start of a level
|
||||
void init_morphs();
|
||||
|
||||
morph_data *find_morph_data(object &obj);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,23 +52,23 @@ namespace dcx {
|
|||
|
||||
d_level_unique_morph_object_state LevelUniqueMorphObjectState;
|
||||
|
||||
}
|
||||
|
||||
//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;
|
||||
if (Newdemo_state == ND_STATE_PLAYBACK) {
|
||||
morph_objects[0].obj = &obj;
|
||||
morph_objects[0] = make_unique<morph_data>(obj);
|
||||
return &morph_objects[0];
|
||||
}
|
||||
|
||||
range_for (auto &i, morph_objects)
|
||||
if (i.obj == &obj)
|
||||
if (i && i->obj == &obj)
|
||||
return &i;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void assign_max(fix &a, const fix &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
|
||||
void do_morph_frame(object &obj)
|
||||
{
|
||||
morph_data *md;
|
||||
const auto umd = find_morph_data(obj);
|
||||
|
||||
md = find_morph_data(obj);
|
||||
|
||||
if (md == NULL) { //maybe loaded half-morphed from disk
|
||||
if (!umd) { //maybe loaded half-morphed from disk
|
||||
obj.flags |= OF_SHOULD_BE_DEAD; //..so kill it
|
||||
return;
|
||||
}
|
||||
const auto md = umd->get();
|
||||
assert(md->obj == &obj);
|
||||
|
||||
auto &Polygon_models = LevelSharedPolygonModelState.Polygon_models;
|
||||
|
@ -252,7 +251,7 @@ void do_morph_frame(object &obj)
|
|||
obj.render_type = RT_POLYOBJ;
|
||||
|
||||
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()
|
||||
{
|
||||
auto &morph_objects = LevelUniqueMorphObjectState.morph_objects;
|
||||
range_for (auto &i, morph_objects)
|
||||
i.obj = nullptr;
|
||||
morph_objects = {};
|
||||
}
|
||||
|
||||
|
||||
|
@ -276,21 +274,22 @@ void morph_start(const vmobjptr_t obj)
|
|||
auto &morph_objects = LevelUniqueMorphObjectState.morph_objects;
|
||||
const auto mob = morph_objects.begin();
|
||||
const auto moe = morph_objects.end();
|
||||
const auto mop = [](const morph_data &mo) {
|
||||
return mo.obj == nullptr || mo.obj->type == OBJ_NONE || mo.obj->signature != mo.Morph_sig;
|
||||
const auto mop = [](const std::unique_ptr<morph_data> &pmo) {
|
||||
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);
|
||||
|
||||
if (moi == moe) //no free slots
|
||||
return;
|
||||
|
||||
morph_data *const md = &*moi;
|
||||
*moi = make_unique<morph_data>(obj);
|
||||
morph_data *const md = moi->get();
|
||||
|
||||
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_movement_type = obj->movement_type;
|
||||
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;
|
||||
polymodel *po;
|
||||
morph_data *md;
|
||||
|
||||
md = find_morph_data(obj);
|
||||
Assert(md != NULL);
|
||||
const auto umd = find_morph_data(obj);
|
||||
if (!umd)
|
||||
throw std::runtime_error("missing morph data");
|
||||
const auto md = umd->get();
|
||||
|
||||
auto &Polygon_models = LevelSharedPolygonModelState.Polygon_models;
|
||||
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)
|
||||
{
|
||||
morph_data *md;
|
||||
md = find_morph_data(objp);
|
||||
if (md) {
|
||||
if (const auto umd = find_morph_data(objp))
|
||||
{
|
||||
const auto md = umd->get();
|
||||
md->obj->control_type = md->morph_save_control_type;
|
||||
set_object_movement_type(*md->obj, md->morph_save_movement_type);
|
||||
md->obj->render_type = RT_POLYOBJ;
|
||||
md->obj->mtype.phys_info = md->morph_save_phys_info;
|
||||
md->obj = NULL;
|
||||
umd->reset();
|
||||
} else { //maybe loaded half-morphed from disk
|
||||
objp->flags |= OF_SHOULD_BE_DEAD;
|
||||
objp->render_type = RT_POLYOBJ;
|
||||
|
|
Loading…
Reference in a new issue