Beispiel #1
0
//reads a binary file containing a 3d model
static polymodel *read_model_file(polymodel *pm,const char *filename,robot_info *r)
{
	short version;
	int len, next_chunk;
	ubyte	model_buf[MODEL_BUF_SIZE];

	auto ifile = PHYSFSX_openReadBuffered(filename);
	if (!ifile)
		Error("Can't open file <%s>",filename);

	Assert(PHYSFS_fileLength(ifile) <= MODEL_BUF_SIZE);

	Pof_addr = 0;
	Pof_file_end = PHYSFS_read(ifile, model_buf, 1, PHYSFS_fileLength(ifile));
	ifile.reset();
	const int model_id = pof_read_int(model_buf);

	if (model_id != 0x4f505350) /* 'OPSP' */
		Error("Bad ID in model file <%s>",filename);

	version = pof_read_short(model_buf);
	
	if (version < PM_COMPATIBLE_VERSION || version > PM_OBJFILE_VERSION)
		Error("Bad version (%d) in model file <%s>",version,filename);

	int pof_id;
	while (new_pof_read_int(pof_id, model_buf) == 1)
	{
		pof_id = INTEL_INT(pof_id);
		//id  = pof_read_int(model_buf);
		len = pof_read_int(model_buf);
		next_chunk = Pof_addr + len;

		switch (pof_id)
		{
			case ID_OHDR: {		//Object header
				vms_vector pmmin,pmmax;

				pm->n_models = pof_read_int(model_buf);
				pm->rad = pof_read_int(model_buf);

				Assert(pm->n_models <= MAX_SUBMODELS);

				pof_read_vecs(&pmmin,1,model_buf);
				pof_read_vecs(&pmmax,1,model_buf);

				break;
			}
			
			case ID_SOBJ: {		//Subobject header
				int n;

				n = pof_read_short(model_buf);

				Assert(n < MAX_SUBMODELS);

				pm->submodel_parents[n] = pof_read_short(model_buf);

				pof_read_vecs(&pm->submodel_norms[n],1,model_buf);
				pof_read_vecs(&pm->submodel_pnts[n],1,model_buf);
				pof_read_vecs(&pm->submodel_offsets[n],1,model_buf);

				pm->submodel_rads[n] = pof_read_int(model_buf);		//radius

				pm->submodel_ptrs[n] = pof_read_int(model_buf);	//offset

				break;

			}
			
			#ifndef DRIVE
			case ID_GUNS: {		//List of guns on this object

				if (r) {
					vms_vector gun_dir;

					r->n_guns = pof_read_int(model_buf);

					Assert(r->n_guns <= MAX_GUNS);

					for (int i=0;i<r->n_guns;i++) {
						const uint_fast32_t gun_id = pof_read_short(model_buf);
						/*
						 * D1 v1.0 boss02.pof has id=4 and r->n_guns==4.
						 * Relax the assert to check only for memory
						 * corruption.
						 */
						Assert(gun_id < sizeof(r->gun_submodels) / sizeof(r->gun_submodels[0]));
						auto &submodel = r->gun_submodels[gun_id];
						submodel = pof_read_short(model_buf);
						Assert(submodel != 0xff);
						pof_read_vecs(&r->gun_points[gun_id], 1, model_buf);

						if (version >= 7)
							pof_read_vecs(&gun_dir,1,model_buf);
					}
				}
				else
					pof_cfseek(model_buf,len,SEEK_CUR);

				break;
			}
			
			case ID_ANIM:		//Animation data
				if (r) {
					unsigned n_frames;

					n_frames = pof_read_short(model_buf);

					Assert(n_frames == N_ANIM_STATES);

					for (int m=0;m<pm->n_models;m++)
						range_for (auto &f, partial_range(anim_angs, n_frames))
							pof_read_angs(&f[m], 1, model_buf);


					robot_set_angles(r,pm,anim_angs);
				
				}
				else
					pof_cfseek(model_buf,len,SEEK_CUR);

				break;
			#endif
			
			case ID_TXTR: {		//Texture filename list
				int n;
				char name_buf[128];

				n = pof_read_short(model_buf);
				while (n--) {
					pof_read_string(name_buf,128,model_buf);
				}

				break;
			}
			
			case ID_IDTA:		//Interpreter data
				pm->model_data_size = len;
				pm->model_data = make_unique<ubyte[]>(pm->model_data_size);

				pof_cfread(pm->model_data.get(),1,len,model_buf);

				break;

			default:
				pof_cfseek(model_buf,len,SEEK_CUR);
				break;

		}
		if ( version >= 8 )		// Version 8 needs 4-byte alignment!!!
			pof_cfseek(model_buf,next_chunk,SEEK_SET);
	}
Beispiel #2
0
//------------------------------------------------------------------------------
//reads a binary file containing a 3d model
polymodel *ReadModelFile (polymodel *pm, char *filename, robot_info *r)
{
    CFILE *ifile;
    short version;
    int id, len, next_chunk;
    int anim_flag = 0;
    ubyte *model_buf;

    if (!(model_buf = (ubyte *)d_malloc (MODEL_BUF_SIZE * sizeof (ubyte))))
        Error ("Can't allocate space to read model %s\n", filename);
    if (!(ifile=CFOpen (filename, gameFolders.szDataDir, "rb", 0)))
        Error ("Can't open file <%s>", filename);
    Assert (CFLength (ifile, 0) <= MODEL_BUF_SIZE);
    Pof_addr = 0;
    Pof_file_end = (int) CFRead (model_buf, 1, CFLength (ifile, 0), ifile);
    CFClose (ifile);
    id = pof_read_int (model_buf);
    if (id!=0x4f505350) /* 'OPSP' */
        Error ("Bad ID in model file <%s>", filename);
    version = pof_read_short (model_buf);
    if (version < PM_COMPATIBLE_VERSION || version > PM_OBJFILE_VERSION)
        Error ("Bad version (%d) in model file <%s>", version, filename);
//if (FindArg ("-bspgen"))
//printf ("bspgen -c1");
    while (new_pof_read_int (id, model_buf) == 1) {
        id = INTEL_INT (id);
        //id  = pof_read_int (model_buf);
        len = pof_read_int (model_buf);
        next_chunk = Pof_addr + len;
        switch (id) {
        case ID_OHDR: {		//Object header
            vms_vector pmmin, pmmax;
            pm->n_models = pof_read_int (model_buf);
            pm->rad = pof_read_int (model_buf);
            Assert (pm->n_models <= MAX_SUBMODELS);
            pof_read_vecs (&pmmin, 1, model_buf);
            pof_read_vecs (&pmmax, 1, model_buf);
            if (FindArg ("-bspgen")) {
                vms_vector v;
                fix l;
                VmVecSub (&v, &pmmax, &pmmin);
                l = v.x;
                if (v.y > l)
                    l = v.y;
                if (v.z > l)
                    l = v.z;
                //printf (" -l%.3f", f2fl (l));
            }
            break;
        }

        case ID_SOBJ: {		//Subobject header
            int n = pof_read_short (model_buf);
            Assert (n < MAX_SUBMODELS);
            anim_flag++;
            pm->submodel_parents [n] = (char) pof_read_short (model_buf);
            pof_read_vecs (&pm->submodel_norms [n], 1, model_buf);
            pof_read_vecs (&pm->submodel_pnts [n], 1, model_buf);
            pof_read_vecs (&pm->submodel_offsets [n], 1, model_buf);
            pm->submodel_rads [n] = pof_read_int (model_buf);		//radius
            pm->submodel_ptrs [n] = pof_read_int (model_buf);	//offset
            break;
        }

#ifndef DRIVE
        case ID_GUNS: {		//List of guns on this object
            if (r) {
                int i;
                vms_vector gun_dir;
                ubyte gun_used [MAX_GUNS];
                r->n_guns = pof_read_int (model_buf);
                if (r->n_guns)
                    anim_flag++;
                Assert (r->n_guns <= MAX_GUNS);
                for (i = 0; i < r->n_guns; i++)
                    gun_used [i] = 0;
                for (i = 0; i < r->n_guns; i++) {
                    int id = pof_read_short (model_buf);
                    Assert (id < r->n_guns);
                    Assert (gun_used [id] == 0);
                    gun_used [id] = 1;
                    r->gun_submodels [id] = (char) pof_read_short (model_buf);
                    Assert (r->gun_submodels [id] != 0xff);
                    pof_read_vecs (&r->gun_points [id], 1, model_buf);
                    if (version >= 7)
                        pof_read_vecs (&gun_dir, 1, model_buf);
                }
            }
            else
                pof_CFSeek (model_buf, len, SEEK_CUR);
            break;
        }

        case ID_ANIM:		//Animation data
            anim_flag++;
            if (r) {
                int f, m, n_frames = pof_read_short (model_buf);
                Assert (n_frames == N_ANIM_STATES);
                for (m = 0; m <pm->n_models; m++)
                    for (f = 0; f < n_frames; f++)
                        pof_read_angs (&anim_angs [f][m], 1, model_buf);
                robot_set_angles (r, pm, anim_angs);
            }
            else
                pof_CFSeek (model_buf, len, SEEK_CUR);
            break;
#endif

        case ID_TXTR: {		//Texture filename list
            char name_buf [128];
            int n = pof_read_short (model_buf);
            while (n--)
                pof_read_string (name_buf, 128, model_buf);
            break;
        }

        case ID_IDTA:		//Interpreter data
            pm->model_data = d_malloc (len);
            pm->model_data_size = len;
            pof_cfread (pm->model_data, 1, len, model_buf);
            break;

        default:
            pof_CFSeek (model_buf, len, SEEK_CUR);
            break;
        }
        if (version >= 8)		// Version 8 needs 4-byte alignment!!!
            pof_CFSeek (model_buf, next_chunk, SEEK_SET);
    }
//	for (i=0;i<pm->n_models;i++)
//		pm->submodel_ptrs [i] += (int) pm->model_data;
    if (FindArg ("-bspgen")) {
        char *p = strchr (filename, '.');
        *p = 0;
        //if (anim_flag > 1)
        //printf (" -a");
        //printf (" %s.3ds\n", filename);
        *p = '.';
    }
    d_free (model_buf);
#ifdef WORDS_NEED_ALIGNMENT
    G3AlignPolyModelData (pm);
#endif
#if defined (WORDS_BIGENDIAN) || defined (__BIG_ENDIAN__)
    G3SwapPolyModelData (pm->model_data);
#endif
    //verify (pm->model_data);
    return pm;
}
Beispiel #3
0
//reads a binary file containing a 3d model
polymodel *read_model_file(polymodel *pm,char *filename,robot_info *r)
{
	CFILE *ifile;
	short version;
	int id,len, next_chunk;
	int anim_flag = 0;
	ubyte *model_buf;

	model_buf = (ubyte *)d_malloc( MODEL_BUF_SIZE * sizeof(ubyte) );
	if (!model_buf)
		Error("Can't allocate space to read model %s\n", filename);

	if ((ifile=cfopen(filename,"rb"))==NULL) 
		Error("Can't open file <%s>",filename);

	Assert(ifile->size <= MODEL_BUF_SIZE);

	Pof_addr = 0;
	Pof_file_end = cfread(model_buf, 1, cfilelength(ifile), ifile);
	cfclose(ifile);

	id = pof_read_int(model_buf);

	if (id!=0x4f505350) /* 'OPSP' */
		Error("Bad ID in model file <%s>",filename);

	version = pof_read_short(model_buf);
	
	if (version < PM_COMPATIBLE_VERSION || version > PM_OBJFILE_VERSION)
		Error("Bad version (%d) in model file <%s>",version,filename);

	if ( FindArg( "-bspgen" )) 
		printf( "bspgen -c1" );

	while (new_pof_read_int(id,model_buf) == 1) {
		id = INTEL_INT(id);
		//id  = pof_read_int(model_buf);
		len = pof_read_int(model_buf);
		next_chunk = Pof_addr + len;

		switch (id) {

			case ID_OHDR: {		//Object header
				vms_vector pmmin,pmmax;

				//con_printf(DEBUG_LEVEL, "Got chunk OHDR, len=%d\n",len);

				pm->n_models = pof_read_int(model_buf);
				pm->rad = pof_read_int(model_buf);

				Assert(pm->n_models <= MAX_SUBMODELS);

				pof_read_vecs(&pmmin,1,model_buf);
				pof_read_vecs(&pmmax,1,model_buf);

				if ( FindArg( "-bspgen" ))	{
					vms_vector v;
					fix l;
				
					vm_vec_sub(&v, &pmmax, &pmmin );
					l = v.x;
					if ( v.y > l ) l = v.y;					
					if ( v.z > l ) l = v.z;					
													
					printf( " -l%.3f", f2fl(l) );
				}

				break;
			}
			
			case ID_SOBJ: {		//Subobject header
				int n;

				anim_flag++;

				//con_printf(DEBUG_LEVEL, "Got chunk SOBJ, len=%d\n",len);

				n = pof_read_short(model_buf);

				Assert(n < MAX_SUBMODELS);

				pm->submodel_parents[n] = pof_read_short(model_buf);

				pof_read_vecs(&pm->submodel_norms[n],1,model_buf);
				pof_read_vecs(&pm->submodel_pnts[n],1,model_buf);
				pof_read_vecs(&pm->submodel_offsets[n],1,model_buf);

				pm->submodel_rads[n] = pof_read_int(model_buf);		//radius

				pm->submodel_ptrs[n] = pof_read_int(model_buf);	//offset

				break;

			}
			
			#ifndef DRIVE
			case ID_GUNS: {		//List of guns on this object

				//con_printf(DEBUG_LEVEL, "Got chunk GUNS, len=%d\n",len);

				if (r) {
					int i;
					vms_vector gun_dir;
					ubyte gun_used[MAX_GUNS];

					r->n_guns = pof_read_int(model_buf);

					if ( r->n_guns )
						anim_flag++;

					Assert(r->n_guns <= MAX_GUNS);

					for (i=0;i<r->n_guns;i++)
						gun_used[i] = 0;

					for (i=0;i<r->n_guns;i++) {
						int id;

						id = pof_read_short(model_buf);
						Assert(id < r->n_guns);
						Assert(gun_used[id] == 0);
						gun_used[id] = 1;
						r->gun_submodels[id] = pof_read_short(model_buf);
						Assert(r->gun_submodels[id] != 0xff);
						pof_read_vecs(&r->gun_points[id],1,model_buf);

						if (version >= 7)
							pof_read_vecs(&gun_dir,1,model_buf);
					}
				}
				else
					pof_cfseek(model_buf,len,SEEK_CUR);

				break;
			}
			
			case ID_ANIM:		//Animation data
				//con_printf(DEBUG_LEVEL, "Got chunk ANIM, len=%d\n",len);

				anim_flag++;

				if (r) {
					int n_frames,f,m;

					n_frames = pof_read_short(model_buf);

					Assert(n_frames == N_ANIM_STATES);

					for (m=0;m<pm->n_models;m++)
						for (f=0;f<n_frames;f++)
							pof_read_angs(&anim_angs[f][m], 1, model_buf);


					robot_set_angles(r,pm,anim_angs);
				
				}
				else
					pof_cfseek(model_buf,len,SEEK_CUR);

				break;
			#endif
			
			case ID_TXTR: {		//Texture filename list
				int n;
				char name_buf[128];

				//con_printf(DEBUG_LEVEL, "Got chunk TXTR, len=%d\n",len);

				n = pof_read_short(model_buf);
				//con_printf(DEBUG_LEVEL, "  num textures = %d\n",n);
				while (n--) {
					pof_read_string(name_buf,128,model_buf);
					//con_printf(DEBUG_LEVEL, "<%s>\n",name_buf);
				}

				break;
			}
			
			case ID_IDTA:		//Interpreter data
				//con_printf(DEBUG_LEVEL, "Got chunk IDTA, len=%d\n",len);

				pm->model_data = d_malloc(len);
				pm->model_data_size = len;

				pof_cfread(pm->model_data,1,len,model_buf);

				break;

			default:
				//con_printf(DEBUG_LEVEL, "Unknown chunk <%c%c%c%c>, len = %d\n",id,id>>8,id>>16,id>>24,len);
				pof_cfseek(model_buf,len,SEEK_CUR);
				break;

		}
		if ( version >= 8 )		// Version 8 needs 4-byte alignment!!!
			pof_cfseek(model_buf,next_chunk,SEEK_SET);
	}

//	for (i=0;i<pm->n_models;i++)
//		pm->submodel_ptrs[i] += (int) pm->model_data;

	if ( FindArg( "-bspgen" )) {
		char *p = strchr( filename, '.' );
		*p = 0;

		if ( anim_flag > 1 )
			printf( " -a" );

		printf( " %s.3ds\n", filename );
		*p = '.';
	}
	
	d_free(model_buf);

#ifdef WORDS_NEED_ALIGNMENT
	align_polygon_model_data(pm);
#endif
#ifdef WORDS_BIGENDIAN
	swap_polygon_model_data(pm->model_data);
#endif
	//verify(pm->model_data);

	return pm;
}
Beispiel #4
0
//reads a binary file containing a 3d model
polymodel *read_model_file(polymodel *pm,char *filename,robot_info *r)
{
	PHYSFS_file *ifile;
	short version;
	int id,len, next_chunk;
	int anim_flag = 0;
	ubyte	model_buf[MODEL_BUF_SIZE];

	if ((ifile=PHYSFSX_openReadBuffered(filename))==NULL)
		Error("Can't open file <%s>",filename);

	Assert(PHYSFS_fileLength(ifile) <= MODEL_BUF_SIZE);

	Pof_addr = 0;
	Pof_file_end = PHYSFS_read(ifile, model_buf, 1, PHYSFS_fileLength(ifile));
	PHYSFS_close(ifile);

	id = pof_read_int(model_buf);

	if (id!=0x4f505350) /* 'OPSP' */
		Error("Bad ID in model file <%s>",filename);

	version = pof_read_short(model_buf);
	
	if (version < PM_COMPATIBLE_VERSION || version > PM_OBJFILE_VERSION)
		Error("Bad version (%d) in model file <%s>",version,filename);

	while (new_pof_read_int(id,model_buf) == 1) {
		id = INTEL_INT(id);
		//id  = pof_read_int(model_buf);
		len = pof_read_int(model_buf);
		next_chunk = Pof_addr + len;

		switch (id) {

			case ID_OHDR: {		//Object header
				vms_vector pmmin,pmmax;

				pm->n_models = pof_read_int(model_buf);
				pm->rad = pof_read_int(model_buf);

				Assert(pm->n_models <= MAX_SUBMODELS);

				pof_read_vecs(&pmmin,1,model_buf);
				pof_read_vecs(&pmmax,1,model_buf);

				break;
			}
			
			case ID_SOBJ: {		//Subobject header
				int n;

				anim_flag++;

				n = pof_read_short(model_buf);

				Assert(n < MAX_SUBMODELS);

				pm->submodel_parents[n] = pof_read_short(model_buf);

				pof_read_vecs(&pm->submodel_norms[n],1,model_buf);
				pof_read_vecs(&pm->submodel_pnts[n],1,model_buf);
				pof_read_vecs(&pm->submodel_offsets[n],1,model_buf);

				pm->submodel_rads[n] = pof_read_int(model_buf);		//radius

				pm->submodel_ptrs[n] = pof_read_int(model_buf);	//offset

				break;

			}
			
			#ifndef DRIVE
			case ID_GUNS: {		//List of guns on this object

				if (r) {
					int i;
					vms_vector gun_dir;
					ubyte gun_used[MAX_GUNS];

					r->n_guns = pof_read_int(model_buf);

					if ( r->n_guns )
						anim_flag++;

					Assert(r->n_guns <= MAX_GUNS);

					for (i=0;i<r->n_guns;i++)
						gun_used[i] = 0;

					for (i=0;i<r->n_guns;i++) {
						int id;

						id = pof_read_short(model_buf);
						Assert(id < r->n_guns);
						Assert(gun_used[id] == 0);
						(void)gun_used[id];
						r->gun_submodels[id] = pof_read_short(model_buf);
						Assert(r->gun_submodels[id] != 0xff);
						pof_read_vecs(&r->gun_points[id],1,model_buf);

						if (version >= 7)
							pof_read_vecs(&gun_dir,1,model_buf);
					}
				}
				else
					pof_cfseek(model_buf,len,SEEK_CUR);

				break;
			}
			
			case ID_ANIM:		//Animation data
				anim_flag++;

				if (r) {
					int n_frames,f,m;

					n_frames = pof_read_short(model_buf);

					Assert(n_frames == N_ANIM_STATES);

					for (m=0;m<pm->n_models;m++)
						for (f=0;f<n_frames;f++)
							pof_read_angs(&anim_angs[f][m], 1, model_buf);


					robot_set_angles(r,pm,anim_angs);
				
				}
				else
					pof_cfseek(model_buf,len,SEEK_CUR);

				break;
			#endif
			
			case ID_TXTR: {		//Texture filename list
				int n;
				char name_buf[128];

				n = pof_read_short(model_buf);
				while (n--) {
					pof_read_string(name_buf,128,model_buf);
				}

				break;
			}
			
			case ID_IDTA:		//Interpreter data
				pm->model_data = d_malloc(len);
				pm->model_data_size = len;

				pof_cfread(pm->model_data,1,len,model_buf);

				break;

			default:
				pof_cfseek(model_buf,len,SEEK_CUR);
				break;

		}
		if ( version >= 8 )		// Version 8 needs 4-byte alignment!!!
			pof_cfseek(model_buf,next_chunk,SEEK_SET);
	}

#ifdef WORDS_NEED_ALIGNMENT
	align_polygon_model_data(pm);
#endif
#ifdef WORDS_BIGENDIAN
	swap_polygon_model_data(pm->model_data);
#endif
	return pm;
}