From ebb1b7035096b289e86aea1084c2a39f14f20eae Mon Sep 17 00:00:00 2001 From: Kp Date: Thu, 24 Jul 2014 03:25:00 +0000 Subject: [PATCH] Fix polymodel writing on x64 Packed writing a structure containing a pointer, but reading it as an int, is wrong on x64. --- common/include/vecmat.h | 4 ++++ common/main/polyobj.h | 23 +++++++++++++---------- d1x-rebirth/main/bmread.cpp | 2 +- d2x-rebirth/main/bmread.cpp | 6 +++--- similar/main/bm.cpp | 1 - similar/main/polyobj.cpp | 36 +++++++++++------------------------- 6 files changed, 32 insertions(+), 40 deletions(-) diff --git a/common/include/vecmat.h b/common/include/vecmat.h index 1109ddf27..2282210bf 100644 --- a/common/include/vecmat.h +++ b/common/include/vecmat.h @@ -46,6 +46,10 @@ struct vms_vector }; }; +#define DEFINE_SERIAL_VMS_VECTOR_TO_MESSAGE() \ + DEFINE_SERIAL_UDT_TO_MESSAGE(vms_vector, v, (v.x, v.y, v.z)); \ + ASSERT_SERIAL_UDT_MESSAGE_SIZE(vms_vector, 12) + typedef struct vms_vector vms_vector_array; diff --git a/common/main/polyobj.h b/common/main/polyobj.h index 9888e881f..1696af419 100644 --- a/common/main/polyobj.h +++ b/common/main/polyobj.h @@ -35,6 +35,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "piggy.h" #ifdef __cplusplus +#include "pack.h" struct glow_values_t; @@ -55,26 +56,26 @@ extern int Dead_modelnums[MAX_POLYGON_MODELS]; #define MAX_SUBMODELS 10 //used to describe a polygon model -struct polymodel +struct polymodel : prohibit_void_ptr { int n_models; int model_data_size; ubyte *model_data; - int submodel_ptrs[MAX_SUBMODELS]; - vms_vector submodel_offsets[MAX_SUBMODELS]; - vms_vector submodel_norms[MAX_SUBMODELS]; // norm for sep plane - vms_vector submodel_pnts[MAX_SUBMODELS]; // point on sep plane - fix submodel_rads[MAX_SUBMODELS]; // radius for each submodel - ubyte submodel_parents[MAX_SUBMODELS]; // what is parent for each submodel - vms_vector submodel_mins[MAX_SUBMODELS]; - vms_vector submodel_maxs[MAX_SUBMODELS]; + array submodel_ptrs; + array submodel_offsets; + array submodel_norms; // norm for sep plane + array submodel_pnts; // point on sep plane + array submodel_rads; // radius for each submodel + array submodel_parents; // what is parent for each submodel + array submodel_mins; + array submodel_maxs; vms_vector mins,maxs; // min,max for whole model fix rad; ubyte n_textures; ushort first_texture; ubyte simpler_model; // alternate model with less detail (0 if none, model_num+1 else) //vms_vector min,max; -} __pack__; +}; #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) // array of pointers to polygon objects @@ -109,6 +110,7 @@ void draw_model_picture(int mn,vms_angvec *orient_angles); void free_model(polymodel *po); #define MAX_POLYOBJ_TEXTURES 100 +static const unsigned N_D2_POLYGON_MODELS = 166; #endif extern grs_bitmap *texture_list[MAX_POLYOBJ_TEXTURES]; extern bitmap_index texture_list_index[MAX_POLYOBJ_TEXTURES]; @@ -120,6 +122,7 @@ extern g3s_point robot_points[MAX_POLYGON_VECS]; * reads a polymodel structure from a PHYSFS_file */ extern void polymodel_read(polymodel *pm, PHYSFS_file *fp); +void polymodel_write(PHYSFS_file *fp, const polymodel &pm); /* * reads n polymodel structs from a PHYSFS_file diff --git a/d1x-rebirth/main/bmread.cpp b/d1x-rebirth/main/bmread.cpp index 1eb944b7e..9d6af424f 100644 --- a/d1x-rebirth/main/bmread.cpp +++ b/d1x-rebirth/main/bmread.cpp @@ -1777,7 +1777,7 @@ void bm_write_all(PHYSFS_file *fp) PHYSFS_write( fp, &N_polygon_models, sizeof(int), 1); range_for (const auto &p, partial_range(Polygon_models, N_polygon_models)) - PHYSFS_write( fp, &p, sizeof(p), 1); + polymodel_write(fp, p); range_for (const auto &p, partial_range(Polygon_models, N_polygon_models)) PHYSFS_write( fp, p.model_data, sizeof(ubyte), p.model_data_size); diff --git a/d2x-rebirth/main/bmread.cpp b/d2x-rebirth/main/bmread.cpp index 7800b6b5f..f57ca5a46 100644 --- a/d2x-rebirth/main/bmread.cpp +++ b/d2x-rebirth/main/bmread.cpp @@ -2085,7 +2085,6 @@ void bm_read_hostage() //extra items added after the release get written in an additional hamfile #define N_D2_ROBOT_TYPES 66 #define N_D2_ROBOT_JOINTS 1145 -#define N_D2_POLYGON_MODELS 166 #define N_D2_OBJBITMAPS 422 #define N_D2_OBJBITMAPPTRS 502 #define N_D2_WEAPON_TYPES 62 @@ -2158,7 +2157,7 @@ void bm_write_all(PHYSFS_file *fp) t = N_D2_POLYGON_MODELS; PHYSFS_write( fp, &t, sizeof(int), 1 ); range_for (const auto &p, partial_range(Polygon_models, t)) - PHYSFS_write( fp, &p, sizeof(p), 1 ); + polymodel_write(fp, p); PHYSFSX_printf(tfile, "N_polygon_models = %d, Polygon_models array = %d\n", t, (int) sizeof(polymodel)*t); for (i=0; i(), p.submodel_ptrs, p.submodel_offsets, p.submodel_norms, p.submodel_pnts, p.submodel_rads, p.submodel_parents, p.submodel_mins, p.submodel_maxs, p.mins, p.maxs, p.rad, p.n_textures, p.first_texture, p.simpler_model)); +ASSERT_SERIAL_UDT_MESSAGE_SIZE(polymodel, 12 + (10 * 4) + (10 * 3 * sizeof(vms_vector)) + (10 * sizeof(fix)) + 10 + (10 * 2 * sizeof(vms_vector)) + (2 * sizeof(vms_vector)) + 8); + /* * reads a polymodel structure from a PHYSFS_file */ void polymodel_read(polymodel *pm, PHYSFS_file *fp) { - int i; + pm->model_data.reset(); + PHYSFSX_serialize_read(fp, *pm); +} - pm->n_models = PHYSFSX_readInt(fp); - pm->model_data_size = PHYSFSX_readInt(fp); - pm->model_data = (ubyte *)(size_t)PHYSFSX_readInt(fp); // garbage, read it anyway just for consistency - for (i = 0; i < MAX_SUBMODELS; i++) - pm->submodel_ptrs[i] = PHYSFSX_readInt(fp); - for (i = 0; i < MAX_SUBMODELS; i++) - PHYSFSX_readVector(&(pm->submodel_offsets[i]), fp); - for (i = 0; i < MAX_SUBMODELS; i++) - PHYSFSX_readVector(&(pm->submodel_norms[i]), fp); - for (i = 0; i < MAX_SUBMODELS; i++) - PHYSFSX_readVector(&(pm->submodel_pnts[i]), fp); - for (i = 0; i < MAX_SUBMODELS; i++) - pm->submodel_rads[i] = PHYSFSX_readFix(fp); - PHYSFS_read(fp, pm->submodel_parents, MAX_SUBMODELS, 1); - for (i = 0; i < MAX_SUBMODELS; i++) - PHYSFSX_readVector(&(pm->submodel_mins[i]), fp); - for (i = 0; i < MAX_SUBMODELS; i++) - PHYSFSX_readVector(&(pm->submodel_maxs[i]), fp); - PHYSFSX_readVector(&(pm->mins), fp); - PHYSFSX_readVector(&(pm->maxs), fp); - pm->rad = PHYSFSX_readFix(fp); - pm->n_textures = PHYSFSX_readByte(fp); - pm->first_texture = PHYSFSX_readShort(fp); - pm->simpler_model = PHYSFSX_readByte(fp); +void polymodel_write(PHYSFS_file *fp, const polymodel &pm) +{ + PHYSFSX_serialize_write(fp, pm); } /*