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:
Kp 2020-02-01 22:33:31 +00:00
parent c55c7d1bd6
commit cac5f1da56
3 changed files with 36 additions and 31 deletions

View file

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

View file

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

View file

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