diff --git a/code/ai/aicode.cpp b/code/ai/aicode.cpp index bd48755ba8..d632020f39 100644 --- a/code/ai/aicode.cpp +++ b/code/ai/aicode.cpp @@ -13705,7 +13705,7 @@ int ai_acquire_emerge_path(object *pl_objp, int parent_objnum, int allowed_path_ ship_info* parent_sip = &Ship_info[parent_shipp->ship_info_index]; polymodel *pm = model_get( parent_sip->model_num ); - ship_bay *bay = pm->ship_bay; + const auto& bay = pm->ship_bay; if ( bay == nullptr ) { Warning(LOCATION, "Ship %s was set to arrive from fighter bay on object %s, but no fighter bay exists on that ships' model (%s).\n", shipp->ship_name, parent_shipp->ship_name, pm->filename); @@ -13920,9 +13920,8 @@ int ai_find_closest_depart_path(ai_info *aip, polymodel *pm, int allowed_path_ma float dist, min_dist, min_free_dist; vec3d *source; model_path *mp; - ship_bay *bay; - bay = pm->ship_bay; + const auto& bay = pm->ship_bay; best_free_path = best_path = -1; min_free_dist = min_dist = 1e20f; @@ -13999,9 +13998,9 @@ int ai_acquire_depart_path(object *pl_objp, int parent_objnum, int allowed_path_ object *parent_objp = &Objects[parent_objnum]; polymodel *pm = model_get(Ship_info[Ships[parent_objp->instance].ship_info_index].model_num ); - ship_bay *bay = pm->ship_bay; + const auto& bay = pm->ship_bay; - if ( bay == NULL ) + if ( bay == nullptr ) return -1; if ( bay->num_paths <= 0 ) return -1; @@ -14092,11 +14091,10 @@ void ai_bay_depart() // Volition bay code polymodel *pm; - ship_bay *bay; pm = model_get(Ship_info[Ships[Objects[aip->goal_objnum].instance].ship_info_index].model_num); - bay = pm->ship_bay; - if ( bay != NULL ) { + const auto& bay = pm->ship_bay; + if ( bay != nullptr ) { bay->depart_flags &= ~(1<submode_parm0); } diff --git a/code/globalincs/type_traits.h b/code/globalincs/type_traits.h index 386e7adc62..e3140265ef 100644 --- a/code/globalincs/type_traits.h +++ b/code/globalincs/type_traits.h @@ -46,6 +46,30 @@ struct is_dereferenceable_pointer inline constexpr bool is_dereferenceable_pointer_v = is_dereferenceable_pointer::value; +template +struct is_smart_pointer : std::false_type {}; + +template +struct is_smart_pointer, std::shared_ptr>>> : std::true_type {}; + +template +struct is_smart_pointer, std::shared_ptr>>> : std::true_type {}; + +template +struct is_smart_pointer, std::unique_ptr>>> : std::true_type {}; + +template +struct is_smart_pointer, std::unique_ptr>>> : std::true_type {}; + +template +struct is_smart_pointer, std::weak_ptr>>> : std::true_type {}; + +template +struct is_smart_pointer, std::weak_ptr>>> : std::true_type {}; + +template +inline constexpr bool is_smart_pointer_v = is_smart_pointer::value; + template class U> inline constexpr bool is_instance_of_v = std::false_type{}; diff --git a/code/graphics/2d.h b/code/graphics/2d.h index f0b825aa90..94370e52a4 100644 --- a/code/graphics/2d.h +++ b/code/graphics/2d.h @@ -615,9 +615,8 @@ public: }; struct indexed_vertex_source { - void* Vertex_list = nullptr; - void* Index_list = nullptr; - + std::shared_ptr Vertex_list = nullptr; + std::shared_ptr Index_list = nullptr; gr_buffer_handle Vbuffer_handle; size_t Vertex_offset = 0; size_t Base_vertex_offset = 0; diff --git a/code/model/model.h b/code/model/model.h index 0c7c52b78b..f00e59afcc 100644 --- a/code/model/model.h +++ b/code/model/model.h @@ -453,7 +453,7 @@ public: matrix frame_of_reference; // used to be called 'orientation' - this is just used for setting the rotation axis and the animation angles int bsp_data_size; - ubyte *bsp_data; + std::shared_ptr bsp_data; int collision_tree_index; @@ -485,7 +485,7 @@ public: vertex_buffer buffer; vertex_buffer trans_buffer; - vertex *outline_buffer; + std::shared_ptr outline_buffer; uint n_verts_outline; vec3d render_box_min; @@ -508,7 +508,7 @@ public: typedef struct mp_vert { vec3d pos; // xyz coordinates of vertex in object's frame of reference int nturrets; // number of turrets guarding this vertex - int *turret_ids; // array of indices into ship_subsys linked list (can't index using [] though) + std::shared_ptr turret_ids; // array of indices into ship_subsys linked list (can't index using [] though) float radius; // How far the closest obstruction is from this vertex } mp_vert; @@ -517,7 +517,7 @@ typedef struct model_path { char parent_name[MAX_NAME_LEN]; // parent name of submodel that path is linked to in POF int parent_submodel; int nverts; - mp_vert *verts; + std::shared_ptr verts; int goal; // Which of the verts is the one closest to the goal of this path int type; // What this path takes you to... See MP_TYPE_??? defines above for details int value; // This depends on the type. @@ -567,7 +567,7 @@ struct glow_point{ typedef struct thruster_bank { int num_points; - glow_point *points; + std::shared_ptr points; // Engine wash info struct engine_wash_info *wash_info_pointer; // index into Engine_wash_info @@ -590,7 +590,7 @@ typedef struct glow_point_bank { // glow bank structure -Bobboau int submodel_parent; int LOD; int num_points; - glow_point *points; + std::shared_ptr points; int glow_bitmap; int glow_neb_bitmap; } glow_point_bank; @@ -650,7 +650,7 @@ typedef struct dock_bay { int num_slots; int type_flags; // indicates what this docking bay can be used for (i.e. cargo/rearm, etc) int num_spline_paths; // number of spline paths which lead to this docking bay - int *splines; // array of indices into the Spline_path array + std::shared_ptr splines; // array of indices into the Spline_path array int parent_submodel; // if this dockpoint should be relative to a submodel instead of the main model char name[MAX_NAME_LEN]; // name of this docking location vec3d pnt[MAX_DOCK_SLOTS]; @@ -692,14 +692,14 @@ typedef struct shield_vertex { struct shield_info { int nverts; int ntris; - shield_vertex *verts; - shield_tri *tris; + std::shared_ptr verts; + std::shared_ptr tris; - gr_buffer_handle buffer_id; + std::shared_ptr buffer_id; int buffer_n_verts; vertex_layout layout; - shield_info() : nverts(0), ntris(0), verts(NULL), tris(NULL), buffer_id(-1), buffer_n_verts(0), layout() { } + shield_info() : nverts(0), ntris(0), verts(nullptr), tris(nullptr), buffer_id(std::make_shared(gr_buffer_handle::invalid())), buffer_n_verts(0) { } }; #define BSP_LIGHT_TYPE_WEAPON 1 @@ -852,7 +852,7 @@ public: vec3d bounding_box[8]; int num_lights; // how many lights there are - bsp_light * lights; // array of light info + std::shared_ptr lights; // array of light info int n_view_positions; // number of viewing positions available on this ship eye view_positions[MAX_EYES]; //viewing positions. Default to {0,0,0}. in location 0 @@ -866,7 +866,7 @@ public: int n_textures; texture_map maps[MAX_MODEL_TEXTURES]; - bsp_info *submodel; // an array of size n_models of submodel info. + std::shared_ptr submodel; // an array of size n_models of submodel info. // linked lists for special polygon types on this model. Most ships I think will have most // of these. (most ships however, probably won't have approach points). @@ -874,19 +874,19 @@ public: int n_missiles; // number of secondary weapon banks (not counting turrets) int n_docks; // number of docking points int n_thrusters; // number of thrusters on this ship. - w_bank *gun_banks; // array of gun banks - w_bank *missile_banks; // array of missile banks - dock_bay *docking_bays; // array of docking point pairs - thruster_bank *thrusters; // array of thruster objects -- likely to change in the future - ship_bay_t *ship_bay; // contains path indexes for ship bay approach/depart paths + std::shared_ptr gun_banks; // array of gun banks + std::shared_ptr missile_banks; // array of missile banks + std::shared_ptr docking_bays; // array of docking point pairs + std::shared_ptr thrusters; // array of thruster objects -- likely to change in the future + std::shared_ptr ship_bay; // contains path indexes for ship bay approach/depart paths shield_info shield; // new shield information - ubyte *shield_collision_tree; + std::shared_ptr shield_collision_tree; int sldc_size; SCP_vector shield_points; int n_paths; - model_path *paths; + std::shared_ptr paths; // physics info float mass; @@ -894,7 +894,7 @@ public: matrix moment_of_inertia; int num_xc; // number of cross sections - cross_section* xc; // pointer to array of cross sections (used in big ship explosions) + std::shared_ptr xc; // pointer to array of cross sections (used in big ship explosions) int num_split_plane; // number of split planes float split_plane[MAX_SPLIT_PLANE]; // actual split plane z coords (for big ship explosions) @@ -905,13 +905,13 @@ public: #ifndef NDEBUG int ram_used; // How much RAM this model uses int debug_info_size; - char *debug_info; + std::shared_ptr debug_info; #endif int used_this_mission; // used for page-in system, how many times this model has been loaded per mission - taylor int n_glow_point_banks; // number of glow points on this ship. -Bobboau - glow_point_bank *glow_point_banks; // array of glow objects -Bobboau + std::shared_ptr glow_point_banks; // array of glow objects -Bobboau indexed_vertex_source vert_source; diff --git a/code/model/modelcollide.cpp b/code/model/modelcollide.cpp index 1ebfeb9313..cb26b7e27a 100644 --- a/code/model/modelcollide.cpp +++ b/code/model/modelcollide.cpp @@ -859,7 +859,7 @@ bool mc_shield_check_common(shield_tri *tri) // also finds the uv's where the ray hit. if ( fvi_point_face(&hitpoint, 3, points, &tri->norm, NULL,NULL,NULL ) ) { Mc->hit_dist = dist; - Mc->shield_hit_tri = (int)(tri - Mc_pm->shield.tris); + Mc->shield_hit_tri = (int)(tri - Mc_pm->shield.tris.get()); Mc->hit_point = hitpoint; Mc->hit_normal = tri->norm; Mc->hit_submodel = -1; @@ -877,7 +877,7 @@ bool mc_shield_check_common(shield_tri *tri) // same behavior whether face or edge // normal, edge_hit, hit_point all updated thru sphereline_face sphere_check_closest_shield_dist = Mc->hit_dist; - Mc->shield_hit_tri = (int)(tri - Mc_pm->shield.tris); + Mc->shield_hit_tri = (int)(tri - Mc_pm->shield.tris.get()); Mc->hit_submodel = -1; Mc->num_hits++; return true; // We hit, so we're done @@ -893,22 +893,22 @@ bool mc_check_sldc(int offset) if (offset > Mc_pm->sldc_size - 5) //no way is this big enough return false; - int* type_p = (int*)(Mc_pm->shield_collision_tree + offset); + int* type_p = (int*)(Mc_pm->shield_collision_tree.get() + offset); // not used //int *size_p = (int *)(Mc_pm->shield_collision_tree+offset+4); // split and polygons - auto* minbox_p = (vec3d*)(Mc_pm->shield_collision_tree + offset + 8); - auto* maxbox_p = (vec3d*)(Mc_pm->shield_collision_tree + offset + 20); + auto* minbox_p = (vec3d*)(Mc_pm->shield_collision_tree.get() + offset + 8); + auto* maxbox_p = (vec3d*)(Mc_pm->shield_collision_tree.get() + offset + 20); // split - auto* front_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree + offset + 32); - auto* back_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree + offset + 36); + auto* front_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree.get() + offset + 32); + auto* back_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree.get() + offset + 36); // polygons - auto* num_polygons_p = (unsigned int*)(Mc_pm->shield_collision_tree + offset + 32); + auto* num_polygons_p = (unsigned int*)(Mc_pm->shield_collision_tree.get() + offset + 32); - auto* shld_polys = (unsigned int*)(Mc_pm->shield_collision_tree + offset + 36); + auto* shld_polys = (unsigned int*)(Mc_pm->shield_collision_tree.get() + offset + 36); diff --git a/code/model/modelinterp.cpp b/code/model/modelinterp.cpp index 61e2fb51d6..5d026902aa 100644 --- a/code/model/modelinterp.cpp +++ b/code/model/modelinterp.cpp @@ -1275,7 +1275,7 @@ int submodel_get_num_polys(int model_num, int submodel_num ) pm = model_get(model_num); - return submodel_get_num_polys_sub( pm->submodel[submodel_num].bsp_data ); + return submodel_get_num_polys_sub( pm->submodel[submodel_num].bsp_data.get() ); } /** @@ -1876,9 +1876,9 @@ void model_interp_submit_buffers(indexed_vertex_source *vert_src, size_t vertex_ return; } - if ( vert_src->Vertex_list != NULL ) { + if ( vert_src->Vertex_list != nullptr ) { size_t offset; - gr_heap_allocate(GpuHeap::ModelVertex, vert_src->Vertex_list_size, vert_src->Vertex_list, offset, vert_src->Vbuffer_handle); + gr_heap_allocate(GpuHeap::ModelVertex, vert_src->Vertex_list_size, vert_src->Vertex_list.get(), offset, vert_src->Vbuffer_handle); // If this happens then someone must have allocated something from the heap with a different stride than what we // are using. @@ -1886,15 +1886,13 @@ void model_interp_submit_buffers(indexed_vertex_source *vert_src, size_t vertex_ vert_src->Base_vertex_offset = offset / vertex_stride; vert_src->Vertex_offset = offset; - vm_free(vert_src->Vertex_list); - vert_src->Vertex_list = NULL; + vert_src->Vertex_list.reset(); } - if ( vert_src->Index_list != NULL ) { - gr_heap_allocate(GpuHeap::ModelIndex, vert_src->Index_list_size, vert_src->Index_list, vert_src->Index_offset, vert_src->Ibuffer_handle); + if ( vert_src->Index_list != nullptr ) { + gr_heap_allocate(GpuHeap::ModelIndex, vert_src->Index_list_size, vert_src->Index_list.get(), vert_src->Index_offset, vert_src->Ibuffer_handle); - vm_free(vert_src->Index_list); - vert_src->Index_list = NULL; + vert_src->Index_list.reset(); } } @@ -1908,30 +1906,26 @@ bool model_interp_pack_buffer(indexed_vertex_source *vert_src, vertex_buffer *vb int i, n_verts = 0; size_t j; - if ( vert_src->Vertex_list == NULL ) { - vert_src->Vertex_list = vm_malloc(vert_src->Vertex_list_size); + if ( vert_src->Vertex_list == nullptr ) { + vert_src->Vertex_list = make_shared(vert_src->Vertex_list_size); // return invalid if we don't have the memory - if ( vert_src->Vertex_list == NULL ) { + if ( vert_src->Vertex_list == nullptr ) { return false; } - - memset(vert_src->Vertex_list, 0, vert_src->Vertex_list_size); } - if ( vert_src->Index_list == NULL ) { - vert_src->Index_list = vm_malloc(vert_src->Index_list_size); + if ( vert_src->Index_list == nullptr ) { + vert_src->Index_list = make_shared(vert_src->Index_list_size); // return invalid if we don't have the memory - if ( vert_src->Index_list == NULL ) { + if ( vert_src->Index_list == nullptr ) { return false; } - - memset(vert_src->Index_list, 0, vert_src->Index_list_size); } // bump to our index in the array - auto array = reinterpret_cast(static_cast(vert_src->Vertex_list) + (vb->vertex_offset)); + auto array = reinterpret_cast(vert_src->Vertex_list.get() + vb->vertex_offset); // generate the vertex array n_verts = vb->model_list->n_verts; @@ -1997,7 +1991,7 @@ bool model_interp_pack_buffer(indexed_vertex_source *vert_src, vertex_buffer *vb const uint *index = tex_buf->get_index(); // bump to our spot in the buffer - auto ibuf = static_cast(vert_src->Index_list) + offset; + auto ibuf = vert_src->Index_list.get() + offset; if ( vb->tex_buf[j].flags & VB_FLAG_LARGE_INDEX ) { memcpy(ibuf, index, n_verts * sizeof(uint)); @@ -2109,7 +2103,7 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn, const model_read_def int milliseconds = timer_get_milliseconds(); - auto bsp_polies = new bsp_polygon_data(model->bsp_data, model->bsp_data_size); + auto bsp_polies = new bsp_polygon_data(model->bsp_data.get(), model->bsp_data_size); auto textureReplace = deferredTasks.texture_replacements.find(mn); if (textureReplace != deferredTasks.texture_replacements.end()) @@ -2141,9 +2135,9 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn, const model_read_def if ( outline_n_lines > 0 ) { model->n_verts_outline = outline_n_lines * 2; - model->outline_buffer = (vertex*)vm_malloc(sizeof(vertex) * model->n_verts_outline); + model->outline_buffer = make_shared(model->n_verts_outline); - bsp_polies->generate_lines(-1, model->outline_buffer); + bsp_polies->generate_lines(-1, model->outline_buffer.get()); } // done with the bsp now that we have the vertex data @@ -2516,14 +2510,16 @@ void model_interp_process_shield_mesh(polymodel * pm) } if ( !buffer.empty() ) { - pm->shield.buffer_id = gr_create_buffer(BufferType::Vertex, BufferUsageHint::Static); - pm->shield.buffer_n_verts = n_verts; - gr_update_buffer_data(pm->shield.buffer_id, buffer.size() * sizeof(vec3d), &buffer[0]); + if (*pm->shield.buffer_id == gr_buffer_handle::invalid()) { + *pm->shield.buffer_id = gr_create_buffer(BufferType::Vertex, BufferUsageHint::Static); + pm->shield.buffer_n_verts = n_verts; + gr_update_buffer_data(*pm->shield.buffer_id, buffer.size() * sizeof(vec3d), buffer.data()); - pm->shield.layout.add_vertex_component(vertex_format_data::POSITION3, sizeof(vec3d) * 2, 0); - pm->shield.layout.add_vertex_component(vertex_format_data::NORMAL, sizeof(vec3d) * 2, sizeof(vec3d)); + pm->shield.layout.add_vertex_component(vertex_format_data::POSITION3, sizeof(vec3d) * 2, 0); + pm->shield.layout.add_vertex_component(vertex_format_data::NORMAL, sizeof(vec3d) * 2, sizeof(vec3d)); + } } else { - pm->shield.buffer_id = gr_buffer_handle::invalid(); + *pm->shield.buffer_id = gr_buffer_handle::invalid(); } } @@ -3233,5 +3229,5 @@ void bsp_polygon_data::replace_textures_used(const SCP_map& replacemen } SCP_set model_get_textures_used(const polymodel* pm, int submodel) { - return bsp_polygon_data{ pm->submodel[submodel].bsp_data, pm->submodel[submodel].bsp_data_size }.get_textures_used(); + return bsp_polygon_data{ pm->submodel[submodel].bsp_data.get(), pm->submodel[submodel].bsp_data_size }.get_textures_used(); } diff --git a/code/model/modelread.cpp b/code/model/modelread.cpp index 53fe8e80e2..36701d2404 100644 --- a/code/model/modelread.cpp +++ b/code/model/modelread.cpp @@ -186,112 +186,24 @@ public: SCP_unordered_map Intrinsic_motions; - void model_free(polymodel* pm) { - int i, j; - safe_kill(pm->ship_bay); - - if (pm->paths) { - for (i = 0; i < pm->n_paths; i++) { - for (j = 0; j < pm->paths[i].nverts; j++) { - if (pm->paths[i].verts[j].turret_ids) { - vm_free(pm->paths[i].verts[j].turret_ids); - } - } - if (pm->paths[i].verts) { - vm_free(pm->paths[i].verts); - } - } - vm_free(pm->paths); - } - - if (pm->shield.verts) { - vm_free(pm->shield.verts); - } - - if (pm->shield.tris) { - vm_free(pm->shield.tris); - } - - if (pm->gun_banks) { // NOLINT - delete[] pm->gun_banks; - } - - if (pm->missile_banks) { // NOLINT - delete[] pm->missile_banks; - } - - if (pm->docking_bays) { - for (i = 0; i < pm->n_docks; i++) { - if (pm->docking_bays[i].splines) { - vm_free(pm->docking_bays[i].splines); - } - } - vm_free(pm->docking_bays); - } - - - if (pm->thrusters) { - for (i = 0; i < pm->n_thrusters; i++) { - if (pm->thrusters[i].points) - vm_free(pm->thrusters[i].points); - } - - vm_free(pm->thrusters); - } - - if (pm->glow_point_banks) { // free the glows!!! -Bobboau - for (i = 0; i < pm->n_glow_point_banks; i++) { - if (pm->glow_point_banks[i].points) - vm_free(pm->glow_point_banks[i].points); - } - - vm_free(pm->glow_point_banks); - } - -#ifndef NDEBUG - if (pm->debug_info) { - vm_free(pm->debug_info); - } -#endif + int i; if (pm->submodel) { for (i = 0; i < pm->n_models; i++) { pm->submodel[i].buffer.clear(); - if (pm->submodel[i].bsp_data) { - vm_free(pm->submodel[i].bsp_data); - } - if (pm->submodel[i].collision_tree_index >= 0) { model_remove_bsp_collision_tree(pm->submodel[i].collision_tree_index); - } - - if (pm->submodel[i].outline_buffer != nullptr) { - vm_free(pm->submodel[i].outline_buffer); - pm->submodel[i].outline_buffer = nullptr; + pm->submodel[i].collision_tree_index = 0; } } - - delete[] pm->submodel; } - if (pm->xc) { - vm_free(pm->xc); - } - - if (pm->lights) { - vm_free(pm->lights); - } - - if (pm->shield_collision_tree) { - vm_free(pm->shield_collision_tree); - } - - if (pm->shield.buffer_id.isValid()) { - gr_delete_buffer(pm->shield.buffer_id); - pm->shield.buffer_id = gr_buffer_handle::invalid(); + if (pm->shield.buffer_id->isValid()) { + gr_delete_buffer(*pm->shield.buffer_id); + *pm->shield.buffer_id = gr_buffer_handle::invalid(); pm->shield.buffer_n_verts = 0; } @@ -303,10 +215,7 @@ void model_free(polymodel* pm) pm->vert_source.Base_vertex_offset = 0; } - if (pm->vert_source.Vertex_list != NULL) { - vm_free(pm->vert_source.Vertex_list); - pm->vert_source.Vertex_list = NULL; - } + pm->vert_source.Vertex_list.reset(); if (pm->vert_source.Ibuffer_handle.isValid()) { gr_heap_deallocate(GpuHeap::ModelIndex, pm->vert_source.Index_offset); @@ -315,10 +224,7 @@ void model_free(polymodel* pm) pm->vert_source.Index_offset = 0; } - if (pm->vert_source.Index_list != NULL) { - vm_free(pm->vert_source.Index_list); - pm->vert_source.Index_list = NULL; - } + pm->vert_source.Index_list.reset(); pm->vert_source.Vertex_list_size = 0; pm->vert_source.Index_list_size = 0; @@ -1652,8 +1558,6 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, } pm->version = version; - Assert(strlen(filename) < FILESPEC_LENGTH ); - strcpy_s(pm->filename, filename); memset( &pm->view_positions, 0, sizeof(pm->view_positions) ); @@ -1708,7 +1612,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, Warning(LOCATION, "Model <%s> has a radius <= 0.00001f\n", filename); } - pm->submodel = new bsp_info[MAX(1,pm->n_models)]; + pm->submodel = make_shared(MAX(1,pm->n_models)); //Assert(pm->n_models <= MAX_SUBMODELS); @@ -1801,11 +1705,11 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, } // read in cross section info - pm->xc = NULL; + pm->xc = nullptr; if ( pm->version >= 2014 ) { pm->num_xc = cfread_int(fp); if (pm->num_xc > 0) { - pm->xc = (cross_section*) vm_malloc(pm->num_xc*sizeof(cross_section)); + pm->xc = make_shared(pm->num_xc); for (i=0; inum_xc; i++) { pm->xc[i].z = cfread_float(fp); pm->xc[i].radius = cfread_float(fp); @@ -1820,7 +1724,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, //mprintf(( "Found %d lights!\n", pm->num_lights )); if (pm->num_lights > 0) { - pm->lights = (bsp_light *)vm_malloc( sizeof(bsp_light)*pm->num_lights ); + pm->lights = make_shared(pm->num_lights ); for (i=0; inum_lights; i++ ) { cfread_vector(&pm->lights[i].pos,fp); pm->lights[i].type = cfread_int(fp); @@ -2112,9 +2016,9 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, { sm->bsp_data_size = cfread_int(fp); if (sm->bsp_data_size > 0) { - sm->bsp_data = reinterpret_cast(vm_malloc(sm->bsp_data_size)); - cfread(sm->bsp_data, 1, sm->bsp_data_size, fp); - swap_bsp_data(pm, sm->bsp_data); + sm->bsp_data = make_shared(sm->bsp_data_size); + cfread(sm->bsp_data.get(), 1, sm->bsp_data_size, fp); + swap_bsp_data(pm, sm->bsp_data.get()); } else { sm->bsp_data = nullptr; @@ -2125,28 +2029,27 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, sm->bsp_data_size = cfread_int(fp); if (sm->bsp_data_size > 0) { - auto bsp_data = reinterpret_cast(vm_malloc(sm->bsp_data_size)); + auto bsp_data = make_shared(sm->bsp_data_size); - cfread(bsp_data, 1, sm->bsp_data_size, fp); + cfread(bsp_data.get(), 1, sm->bsp_data_size, fp); // byte swap first thing - swap_bsp_data(pm, bsp_data); + swap_bsp_data(pm, bsp_data.get()); extern bool Cmdline_no_bsp_align; if (Cmdline_no_bsp_align) { sm->bsp_data = bsp_data; } else { - auto bsp_data_size_aligned = align_bsp_data(bsp_data, nullptr, sm->bsp_data_size); + auto bsp_data_size_aligned = align_bsp_data(bsp_data.get(), nullptr, sm->bsp_data_size); if (bsp_data_size_aligned != static_cast(sm->bsp_data_size)) { - auto bsp_data_aligned = reinterpret_cast(vm_malloc(bsp_data_size_aligned)); + auto bsp_data_aligned = make_shared(bsp_data_size_aligned); - align_bsp_data(bsp_data, bsp_data_aligned, sm->bsp_data_size); + align_bsp_data(bsp_data.get(), bsp_data_aligned.get(), sm->bsp_data_size); // release unaligned data - vm_free(bsp_data); - bsp_data = nullptr; + bsp_data.reset(); nprintf(("Model", "BSP ALIGN => %s:%s resized by %d bytes (%d total)\n", pm->filename, sm->name, bsp_data_size_aligned - sm->bsp_data_size, bsp_data_size_aligned)); @@ -2190,9 +2093,9 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, //mprintf(("SLDC Shield Collision Tree was %d bytes in size\n", pm->sldc_size)); pm->sldc_size = convert_sldc_to_slc2(sldc_tree.get(), slc2_tree.get(), pm->sldc_size); //mprintf(("SLC2 Shield Collision Tree is %d bytes in size\n", pm->sldc_size)); - pm->shield_collision_tree = (ubyte*)vm_malloc(pm->sldc_size); //sldc_size is slc2 size, reused variable - memcpy(pm->shield_collision_tree, slc2_tree.get(), pm->sldc_size); - swap_sldc_data(pm->shield_collision_tree); + pm->shield_collision_tree = make_shared(pm->sldc_size); //sldc_size is slc2 size, reused variable + memcpy(pm->shield_collision_tree.get(), slc2_tree.get(), pm->sldc_size); + swap_sldc_data(pm->shield_collision_tree.get()); } } break; @@ -2201,9 +2104,9 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, { if (pm->version >= 2200) { pm->sldc_size = cfread_int(fp); - pm->shield_collision_tree = (ubyte*)vm_malloc(pm->sldc_size); - cfread(pm->shield_collision_tree, 1, pm->sldc_size, fp); - swap_sldc_data(pm->shield_collision_tree); + pm->shield_collision_tree = make_shared(pm->sldc_size); + cfread(pm->shield_collision_tree.get(), 1, pm->sldc_size, fp); + swap_sldc_data(pm->shield_collision_tree.get()); //mprintf(( "SLC2 Shield Collision Tree, %d bytes in size\n", pm->sldc_size)); } } @@ -2214,7 +2117,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, pm->shield.nverts = cfread_int( fp ); // get the number of vertices in the list if (pm->shield.nverts > 0) { - pm->shield.verts = (shield_vertex *)vm_malloc(pm->shield.nverts * sizeof(shield_vertex) ); + pm->shield.verts = make_shared(pm->shield.nverts); Assert( pm->shield.verts ); for ( i = 0; i < pm->shield.nverts; i++ ) { // read in the vertex list cfread_vector( &(pm->shield.verts[i].pos), fp ); @@ -2224,7 +2127,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, pm->shield.ntris = cfread_int( fp ); // get the number of triangles that compose the shield if (pm->shield.ntris > 0) { - pm->shield.tris = (shield_tri *)vm_malloc(pm->shield.ntris * sizeof(shield_tri) ); + pm->shield.tris = make_shared(pm->shield.ntris); Assert( pm->shield.tris ); for ( i = 0; i < pm->shield.ntris; i++ ) { cfread_vector( &temp_vec, fp ); @@ -2257,11 +2160,11 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, case ID_MPNT: { int n_weps = cfread_int(fp); - w_bank *wep_banks = nullptr; + std::shared_ptr wep_banks = nullptr; if (n_weps > 0) { - wep_banks = new w_bank[n_weps]; + wep_banks = make_shared(n_weps); for (i = 0; i < n_weps; ++i) { w_bank *bank = &wep_banks[i]; @@ -2310,8 +2213,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, pm->n_docks = cfread_int(fp); if (pm->n_docks > 0) { - pm->docking_bays = (dock_bay *)vm_malloc(sizeof(dock_bay) * pm->n_docks); - Assert( pm->docking_bays != NULL ); + pm->docking_bays = make_shared(pm->n_docks); for (i = 0; i < pm->n_docks; i++ ) { char *p; @@ -2340,7 +2242,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, bay->num_spline_paths = cfread_int( fp ); if ( bay->num_spline_paths > 0 ) { - bay->splines = (int *)vm_malloc(sizeof(int) * bay->num_spline_paths); + bay->splines = make_shared(bay->num_spline_paths); for ( j = 0; j < bay->num_spline_paths; j++ ) bay->splines[j] = cfread_int(fp); } else { @@ -2417,13 +2319,10 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, int gpb_num = cfread_int(fp); pm->n_glow_point_banks = gpb_num; - pm->glow_point_banks = NULL; + pm->glow_point_banks = nullptr; if (gpb_num > 0) - { - pm->glow_point_banks = (glow_point_bank *) vm_malloc(sizeof(glow_point_bank) * gpb_num); - Assert(pm->glow_point_banks != NULL); - } + pm->glow_point_banks = make_shared(gpb_num); for (int gpb = 0; gpb < gpb_num; gpb++) { @@ -2438,12 +2337,12 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, bank->LOD = cfread_int(fp); bank->type = cfread_int(fp); bank->num_points = cfread_int(fp); - bank->points = NULL; + bank->points = nullptr; bank->glow_bitmap = -1; bank->glow_neb_bitmap = -1; if (bank->num_points > 0) - bank->points = (glow_point *) vm_malloc(sizeof(glow_point) * bank->num_points); + bank->points = make_shared(bank->num_points); //if((bank->off_time > 0) && (bank->disp_time > 0)) //bank->is_on = false; @@ -2517,17 +2416,16 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, pm->n_thrusters = cfread_int(fp); if (pm->n_thrusters > 0) { - pm->thrusters = (thruster_bank *)vm_malloc(sizeof(thruster_bank) * pm->n_thrusters); - Assert( pm->thrusters != NULL ); + pm->thrusters = make_shared(pm->n_thrusters); for (i = 0; i < pm->n_thrusters; i++ ) { thruster_bank *bank = &pm->thrusters[i]; bank->num_points = cfread_int(fp); - bank->points = NULL; + bank->points = nullptr; if (bank->num_points > 0) - bank->points = (glow_point *) vm_malloc(sizeof(glow_point) * bank->num_points); + bank->points = make_shared(bank->num_points); bank->obj_num = -1; bank->submodel_num = -1; @@ -2703,10 +2601,8 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, #ifndef NDEBUG pm->debug_info_size = len; - pm->debug_info = (char *)vm_malloc(pm->debug_info_size+1); - Assert(pm->debug_info!=NULL); - memset(pm->debug_info,0,len+1); - cfread( pm->debug_info, 1, len, fp ); + pm->debug_info = make_shared(pm->debug_info_size+1); + cfread( pm->debug_info.get(), 1, len, fp ); #endif break; @@ -2720,10 +2616,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, break; } - pm->paths = (model_path *)vm_malloc(sizeof(model_path)*pm->n_paths); - Assert( pm->paths != NULL ); - - memset( pm->paths, 0, sizeof(model_path) * pm->n_paths ); + pm->paths = make_shared(pm->n_paths); for (i=0; in_paths; i++ ) { cfread_string_len(pm->paths[i].name, MAX_NAME_LEN, fp); @@ -2757,12 +2650,10 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, } pm->paths[i].nverts = cfread_int( fp ); - pm->paths[i].verts = (mp_vert *)vm_malloc( sizeof(mp_vert) * pm->paths[i].nverts ); + pm->paths[i].verts = make_shared(pm->paths[i].nverts); pm->paths[i].goal = pm->paths[i].nverts - 1; pm->paths[i].type = MP_TYPE_UNUSED; pm->paths[i].value = 0; - Assert(pm->paths[i].verts!=NULL); - memset( pm->paths[i].verts, 0, sizeof(mp_vert) * pm->paths[i].nverts ); for (j=0; jpaths[i].nverts; j++ ) { cfread_vector(&pm->paths[i].verts[j].pos,fp ); @@ -2775,7 +2666,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, pm->paths[i].verts[j].nturrets = nturrets; if (nturrets > 0) { - pm->paths[i].verts[j].turret_ids = (int *)vm_malloc( sizeof(int) * nturrets ); + pm->paths[i].verts[j].turret_ids = make_shared(nturrets); for ( k = 0; k < nturrets; k++ ) pm->paths[i].verts[j].turret_ids[k] = cfread_int( fp ); } @@ -3051,6 +2942,9 @@ modelread_status read_model_file(polymodel* pm, const char* filename, ErrorType //reads a binary file containing a 3d model modelread_status read_and_process_model_file(polymodel* pm, const char* filename, int n_subsystems, model_subsystem* subsystems, ErrorType error_type, model_read_deferred_tasks& deferredTasks) { + Assert(strlen(filename) < FILESPEC_LENGTH ); + strcpy_s(pm->filename, filename); + modelread_status status = read_model_file(pm, filename, error_type, deferredTasks); //By now, we have finished reading this model. If it was virtual, we might have accumulated cache. @@ -3558,8 +3452,8 @@ int model_load(const char* filename, ship_info* sip, ErrorType error_type, bool pm->submodel[i].collision_tree_index = model_create_bsp_collision_tree(); bsp_collision_tree* tree = model_get_bsp_collision_tree(pm->submodel[i].collision_tree_index); - Macro_ubyte_bounds = pm->submodel[i].bsp_data + pm->submodel[i].bsp_data_size; - model_collide_parse_bsp(tree, pm->submodel[i].bsp_data, pm->version); + Macro_ubyte_bounds = pm->submodel[i].bsp_data.get() + pm->submodel[i].bsp_data_size; + model_collide_parse_bsp(tree, pm->submodel[i].bsp_data.get(), pm->version); Macro_ubyte_bounds = nullptr; } @@ -3742,10 +3636,9 @@ void model_set_bay_path_nums(polymodel *pm) { int i; - if (pm->ship_bay != NULL) + if (pm->ship_bay != nullptr) { - vm_free(pm->ship_bay); - pm->ship_bay = NULL; + pm->ship_bay.reset(); } /* @@ -3756,8 +3649,7 @@ void model_set_bay_path_nums(polymodel *pm) */ // malloc out storage for the path information - pm->ship_bay = (ship_bay *) vm_malloc(sizeof(ship_bay)); - Assert(pm->ship_bay != NULL); + pm->ship_bay = make_shared(); pm->ship_bay->num_paths = 0; // TODO: determine if zeroing out here is affecting any earlier initializations diff --git a/code/model/modelrender.cpp b/code/model/modelrender.cpp index bfad90a4d1..56e6fd2cbf 100644 --- a/code/model/modelrender.cpp +++ b/code/model/modelrender.cpp @@ -1293,7 +1293,7 @@ void model_render_children_buffers(model_draw_list* scene, model_material *rende if ( (model_flags & MR_SHOW_OUTLINE || model_flags & MR_SHOW_OUTLINE_HTL || model_flags & MR_SHOW_OUTLINE_PRESET) && sm->outline_buffer != nullptr ) { color outline_color = interp->get_color(); - scene->add_outline(sm->outline_buffer, sm->n_verts_outline, &outline_color); + scene->add_outline(sm->outline_buffer.get(), sm->n_verts_outline, &outline_color); } else { if ( trans_buffer && sm->trans_buffer.flags & VB_FLAG_TRANS ) { model_render_buffers(scene, rendering_material, interp, &sm->trans_buffer, pm, mn, detail_level, tmap_flags); @@ -2932,7 +2932,7 @@ void model_render_queue(const model_render_params* interp, model_draw_list* scen if ( (is_outlines_only || is_outlines_only_htl) && pm->submodel[detail_model_num].outline_buffer != NULL ) { color outline_color = interp->get_color(); - scene->add_outline(pm->submodel[detail_model_num].outline_buffer, pm->submodel[detail_model_num].n_verts_outline, &outline_color); + scene->add_outline(pm->submodel[detail_model_num].outline_buffer.get(), pm->submodel[detail_model_num].n_verts_outline, &outline_color); } else { model_render_buffers(scene, &rendering_material, interp, &pm->submodel[detail_model_num].buffer, pm, detail_model_num, detail_level, tmap_flags); diff --git a/code/model/modelreplace.cpp b/code/model/modelreplace.cpp index 793460ba30..acbb221a36 100644 --- a/code/model/modelreplace.cpp +++ b/code/model/modelreplace.cpp @@ -202,10 +202,12 @@ void virtual_pof_init() { template inline void object_copy_including_array_member_inner(const T& item, T& result, int size, member_t T::* ptm) { - if (vmalloc) - result.*ptm = (member_t)vm_malloc(sizeof(typename std::remove_pointer::type) * (size)); + if constexpr (is_smart_pointer_v>) + result.*ptm = make_shared::element_type[]>(size); + else if constexpr (vmalloc) + result.*ptm = static_cast(vm_malloc(sizeof(std::remove_pointer_t) * size)); else - result.*ptm = new typename std::remove_pointer::type[size]; + result.*ptm = new std::remove_pointer_t[size]; for (int i = 0; i < size; i++) (result.*ptm)[i] = (item.*ptm)[i]; @@ -225,40 +227,19 @@ T object_copy_including_array_member(const T& item, int T::* size, member_t T::* } template -int reallocate_and_copy_array(T*& array, int& size, size_t to_add) { +int reallocate_and_copy_array(std::shared_ptr& array, int& size, size_t to_add) { //Make sure to keep old data - T* oldArray = array; - - Assertion(size >= 0, "Tried to realloc an array of negative size %d!", size); - int size_before = size; - - //Realloc new submodel array of proper size - size += static_cast(to_add); - array = new T[MAX(0,size)]; - - //Copy over old data. Pointers in the struct can still point to old members, we will just delete the outer bsp_info array - for (int i = 0; i < size_before; i++) - array[i] = std::move(oldArray[i]); - delete[] oldArray; - - return size_before; -} - -template -int reallocate_and_copy_array_vmalloc(T*& array, int& size, size_t to_add) { - //Make sure to keep old data - T* oldArray = array; + std::shared_ptr oldArray = array; int size_before = size; //Realloc new submodel array of proper size size += static_cast(to_add); - array = (T*)vm_malloc(sizeof(T) * size); + array = make_shared(size); //Copy over old data. Pointers in the struct can still point to old members, we will just delete the outer bsp_info array for (int i = 0; i < size_before; i++) array[i] = std::move(oldArray[i]); - vm_free(oldArray); return size_before; } @@ -753,10 +734,10 @@ VirtualPOFOperationAddWeapons::VirtualPOFOperationAddWeapons() { void VirtualPOFOperationAddWeapons::process(polymodel* pm, model_read_deferred_tasks& /*deferredTasks*/, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const { auto appendingPM = virtual_pof_build_cache(appendingPOF, depth); - w_bank*& banks = primary ? pm->gun_banks : pm->missile_banks; + auto& banks = primary ? pm->gun_banks : pm->missile_banks; int& n_banks = primary ? pm->n_guns : pm->n_missiles; - const w_bank* const& banks_src = primary ? appendingPM->pm()->gun_banks : appendingPM->pm()->missile_banks; + const auto& banks_src = primary ? appendingPM->pm()->gun_banks : appendingPM->pm()->missile_banks; const int& n_banks_src = primary ? appendingPM->pm()->n_guns : appendingPM->pm()->n_missiles; const int& n_banks_max = primary ? MAX_SHIP_PRIMARY_BANKS : MAX_SHIP_SECONDARY_BANKS; @@ -860,9 +841,9 @@ void VirtualPOFOperationAddDockPoint::process(polymodel* pm, model_read_deferred } } - int destdock = reallocate_and_copy_array_vmalloc(pm->docking_bays, pm->n_docks, 1); + int destdock = reallocate_and_copy_array(pm->docking_bays, pm->n_docks, 1); pm->docking_bays[destdock] = object_copy_including_array_member(appendingPM->docking_bays[dockpoint], &dock_bay::num_spline_paths, &dock_bay::splines); - int splinefrom = reallocate_and_copy_array_vmalloc(pm->paths, pm->n_paths, pm->docking_bays[destdock].num_spline_paths); + int splinefrom = reallocate_and_copy_array(pm->paths, pm->n_paths, pm->docking_bays[destdock].num_spline_paths); for (int i = 0; i < pm->docking_bays[destdock].num_spline_paths; i++) { pm->paths[i + splinefrom] = object_copy_including_array_member(appendingPM->paths[appendingPM->docking_bays[dockpoint].splines[i]], &model_path::nverts, &model_path::verts); @@ -957,7 +938,7 @@ void VirtualPOFOperationAddPath::process(polymodel* pm, model_read_deferred_task return; } - int destpath = reallocate_and_copy_array_vmalloc(pm->paths, pm->n_paths, 1); + int destpath = reallocate_and_copy_array(pm->paths, pm->n_paths, 1); pm->paths[destpath] = object_copy_including_array_member(appendingPM->paths[sourcePathNr], &model_path::nverts, &model_path::verts); if (targetParentSubsystem) { diff --git a/code/ship/shield.cpp b/code/ship/shield.cpp index 7006b720e4..218dacd32c 100644 --- a/code/ship/shield.cpp +++ b/code/ship/shield.cpp @@ -394,7 +394,7 @@ void shield_render_triangle(int texture, float alpha, gshield_tri *trip, matrix void shield_render_decal(polymodel *pm, matrix *orient, vec3d *pos, matrix* hit_orient, vec3d *hit_pos, float hit_radius, int bitmap_id, color *clr) { - if (!pm->shield.buffer_id.isValid() || pm->shield.buffer_n_verts < 3) { + if (!pm->shield.buffer_id->isValid() || pm->shield.buffer_n_verts < 3) { return; } @@ -410,7 +410,7 @@ void shield_render_decal(polymodel *pm, matrix *orient, vec3d *pos, matrix* hit_ material_info.set_impact_transform(*hit_orient, *hit_pos); material_info.set_cull_mode(false); - gr_render_shield_impact(&material_info, PRIM_TYPE_TRIS, &pm->shield.layout, pm->shield.buffer_id, pm->shield.buffer_n_verts); + gr_render_shield_impact(&material_info, PRIM_TYPE_TRIS, &pm->shield.layout, *pm->shield.buffer_id, pm->shield.buffer_n_verts); g3_done_instance(true); } @@ -562,9 +562,8 @@ void render_shields() void create_tris_containing(vec3d *vp, matrix *orient, shield_info *shieldp, vec3d *tcp, vec3d *centerp, float radius, vec3d *rvec, vec3d *uvec) { int i, j; - shield_vertex *verts; - verts = shieldp->verts; + const auto& verts = shieldp->verts; for (i=0; itris[i].used ) { @@ -624,7 +623,7 @@ int get_global_shield_tri() void create_shield_from_triangle(int trinum, matrix *orient, shield_info *shieldp, vec3d *tcp, vec3d *centerp, float radius, vec3d *rvec, vec3d *uvec) { - rs_compute_uvs( &shieldp->tris[trinum], shieldp->verts, tcp, radius, rvec, uvec); + rs_compute_uvs( &shieldp->tris[trinum], shieldp->verts.get(), tcp, radius, rvec, uvec); shieldp->tris[trinum].used = 1; diff --git a/code/ship/ship.cpp b/code/ship/ship.cpp index 7e7a00e94c..6d29132f62 100644 --- a/code/ship/ship.cpp +++ b/code/ship/ship.cpp @@ -12351,7 +12351,7 @@ void change_ship_type(int n, int ship_type, int by_sexp) } // see if this dockpoint is found on the new model under a different name - int new_dockpoint_index = find_item_with_string(pm->docking_bays, pm->n_docks, &dock_bay::name, dockpoint_name); + int new_dockpoint_index = find_item_with_string(pm->docking_bays.get(), pm->n_docks, &dock_bay::name, dockpoint_name); if (new_dockpoint_index >= 0) { dock_ptr->dockpoint_used = new_dockpoint_index; diff --git a/test/src/model/test_modelread.cpp b/test/src/model/test_modelread.cpp index b1e4440fc8..d2cde8b51b 100644 --- a/test/src/model/test_modelread.cpp +++ b/test/src/model/test_modelread.cpp @@ -26,7 +26,7 @@ protected: pm = new polymodel(); pmi = new polymodel_instance(); - pm->submodel = new bsp_info[3]; + pm->submodel = make_shared(3); pmi->submodel = new submodel_instance[3]; pm->submodel[0].parent = -1; @@ -51,7 +51,7 @@ protected: void TearDown() override { test::FSTestFixture::TearDown(); - delete[] pm->submodel; + pm->submodel.reset(); delete[] pmi->submodel; delete pm; delete pmi;