Ejemplo n.º 1
0
/*
=================
Mod_LoadAliasModel
=================
*/
void Mod_LoadAliasModel (model_t *mod, void *buffer)
{
    int					i, j;
    mdl_t				*pinmodel;
    stvert_t			*pinstverts;
    dtriangle_t			*pintriangles;
    int					version, numframes, numskins;
    int					size;
    daliasframetype_t	*pframetype;
    daliasskintype_t	*pskintype;
    int					start, end, total;

    start = Hunk_LowMark ();

    pinmodel = (mdl_t *)buffer;

    version = LittleLong (pinmodel->version);
    if (version != ALIAS_VERSION)
        Sys_Error ("%s has wrong version number (%i should be %i)",
                   mod->name, version, ALIAS_VERSION);

//
// allocate space for a working header, plus all the data except the frames,
// skin and group info
//
    size = 	sizeof (aliashdr_t)
            + (LittleLong (pinmodel->numframes) - 1) *
            sizeof (pheader->frames[0]);
    pheader = Hunk_AllocName (size, loadname);

    mod->flags = LittleLong (pinmodel->flags);

//
// endian-adjust and copy the data, starting with the alias model header
//
    pheader->boundingradius = LittleFloat (pinmodel->boundingradius);
    pheader->numskins = LittleLong (pinmodel->numskins);
    pheader->skinwidth = LittleLong (pinmodel->skinwidth);
    pheader->skinheight = LittleLong (pinmodel->skinheight);

    if (pheader->skinheight > MAX_LBM_HEIGHT)
        Sys_Error ("model %s has a skin taller than %d", mod->name,
                   MAX_LBM_HEIGHT);

    pheader->numverts = LittleLong (pinmodel->numverts);

    if (pheader->numverts <= 0)
        Sys_Error ("model %s has no vertices", mod->name);

    if (pheader->numverts > MAXALIASVERTS)
        Sys_Error ("model %s has too many vertices", mod->name);

    pheader->numtris = LittleLong (pinmodel->numtris);

    if (pheader->numtris <= 0)
        Sys_Error ("model %s has no triangles", mod->name);

    pheader->numframes = LittleLong (pinmodel->numframes);
    numframes = pheader->numframes;
    if (numframes < 1)
        Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes);

    pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
    mod->synctype = LittleLong (pinmodel->synctype);
    mod->numframes = pheader->numframes;

    for (i=0 ; i<3 ; i++)
    {
        pheader->scale[i] = LittleFloat (pinmodel->scale[i]);
        pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]);
        pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]);
    }


//
// load the skins
//
    pskintype = (daliasskintype_t *)&pinmodel[1];
    pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype);

//
// load base s and t vertices
//
    pinstverts = (stvert_t *)pskintype;

    for (i=0 ; i<pheader->numverts ; i++)
    {
        stverts[i].onseam = LittleLong (pinstverts[i].onseam);
        stverts[i].s = LittleLong (pinstverts[i].s);
        stverts[i].t = LittleLong (pinstverts[i].t);
    }

//
// load triangle lists
//
    pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts];

    for (i=0 ; i<pheader->numtris ; i++)
    {
        triangles[i].facesfront = LittleLong (pintriangles[i].facesfront);

        for (j=0 ; j<3 ; j++)
        {
            triangles[i].vertindex[j] =
                LittleLong (pintriangles[i].vertindex[j]);
        }
    }

//
// load the frames
//
    posenum = 0;
    pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris];

    for (i=0 ; i<numframes ; i++)
    {
        aliasframetype_t	frametype;

        frametype = LittleLong (pframetype->type);

        if (frametype == ALIAS_SINGLE)
        {
            pframetype = (daliasframetype_t *)
                         Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]);
        }
        else
        {
            pframetype = (daliasframetype_t *)
                         Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]);
        }
    }

    pheader->numposes = posenum;

    mod->type = mod_alias;

// FIXME: do this right
    mod->mins[0] = mod->mins[1] = mod->mins[2] = -16;
    mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16;

    //
    // build the draw lists
    //
    GL_MakeAliasModelDisplayLists (mod, pheader);

//
// move the complete, relocatable alias model to the cache
//
    end = Hunk_LowMark ();
    total = end - start;

    Cache_Alloc (&mod->cache, total, loadname);
    if (!mod->cache.data)
        return;
    memcpy (mod->cache.data, pheader, total);

    Hunk_FreeToLowMark (start);
}
Ejemplo n.º 2
0
/*
=================
Mod_LoadAliasModel
=================
*/
void Mod_LoadAliasModel (model_t *mod, void *buffer)
{
	int					i, j;
	mdl_t				*pinmodel;
	stvert_t			*pinstverts;
	dtriangle_t			*pintriangles;
	int					version, numframes;
	int					size;
	daliasframetype_t	*pframetype;
	daliasskintype_t	*pskintype;
	int					start, end, total;

	if (!strcmp(loadmodel->name, "progs/player.mdl") ||
		!strcmp(loadmodel->name, "progs/eyes.mdl")) {
		unsigned short crc;
		byte *p;
		int len;
		char st[40];

		CRC_Init(&crc);
		for (len = com_filesize, p = buffer; len; len--, p++)
			CRC_ProcessByte(&crc, *p);
	
		sprintf(st, "%d", (int) crc);
		Info_SetValueForKey (cls.userinfo, 
			!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
			st, MAX_INFO_STRING);

		if (cls.state >= ca_connected) {
			MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
			sprintf(st, "setinfo %s %d", 
				!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
				(int)crc);
			SZ_Print (&cls.netchan.message, st);
		}
	}
	
	start = Hunk_LowMark ();

	pinmodel = (mdl_t *)buffer;

	version = LittleLong (pinmodel->version);
	if (version != ALIAS_VERSION)
		Sys_Error ("%s has wrong version number (%i should be %i)",
				 mod->name, version, ALIAS_VERSION);

//
// allocate space for a working header, plus all the data except the frames,
// skin and group info
//
	size = 	sizeof (aliashdr_t) 
			+ (LittleLong (pinmodel->numframes) - 1) *
			sizeof (pheader->frames[0]);
	pheader = Hunk_AllocName (size, loadname);
	
	mod->flags = LittleLong (pinmodel->flags);

//
// endian-adjust and copy the data, starting with the alias model header
//
	pheader->boundingradius = LittleFloat (pinmodel->boundingradius);
	pheader->numskins = LittleLong (pinmodel->numskins);
	pheader->skinwidth = LittleLong (pinmodel->skinwidth);
	pheader->skinheight = LittleLong (pinmodel->skinheight);

	if (pheader->skinheight > MAX_LBM_HEIGHT)
		Sys_Error ("model %s has a skin taller than %d", mod->name,
				   MAX_LBM_HEIGHT);

	pheader->numverts = LittleLong (pinmodel->numverts);

	if (pheader->numverts <= 0)
		Sys_Error ("model %s has no vertices", mod->name);

	if (pheader->numverts > MAXALIASVERTS)
		Sys_Error ("model %s has too many vertices", mod->name);

	pheader->numtris = LittleLong (pinmodel->numtris);

	if (pheader->numtris <= 0)
		Sys_Error ("model %s has no triangles", mod->name);

	pheader->numframes = LittleLong (pinmodel->numframes);
	numframes = pheader->numframes;
	if (numframes < 1)
		Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes);

	pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
	mod->synctype = LittleLong (pinmodel->synctype);
	mod->numframes = pheader->numframes;

	for (i=0 ; i<3 ; i++)
	{
		pheader->scale[i] = LittleFloat (pinmodel->scale[i]);
		pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]);
		pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]);
	}


//
// load the skins
//
	pskintype = (daliasskintype_t *)&pinmodel[1];
	pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype);

//
// load base s and t vertices
//
	pinstverts = (stvert_t *)pskintype;

	for (i=0 ; i<pheader->numverts ; i++)
	{
		stverts[i].onseam = LittleLong (pinstverts[i].onseam);
		stverts[i].s = LittleLong (pinstverts[i].s);
		stverts[i].t = LittleLong (pinstverts[i].t);
	}

//
// load triangle lists
//
	pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts];

	for (i=0 ; i<pheader->numtris ; i++)
	{
		triangles[i].facesfront = LittleLong (pintriangles[i].facesfront);

		for (j=0 ; j<3 ; j++)
		{
			triangles[i].vertindex[j] =
					LittleLong (pintriangles[i].vertindex[j]);
		}
	}

//
// load the frames
//
	posenum = 0;
	pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris];

	for (i=0 ; i<numframes ; i++)
	{
		aliasframetype_t	frametype;

		frametype = LittleLong (pframetype->type);

		if (frametype == ALIAS_SINGLE)
		{
			pframetype = (daliasframetype_t *)
					Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]);
		}
		else
		{
			pframetype = (daliasframetype_t *)
					Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]);
		}
	}

	pheader->numposes = posenum;

	mod->type = mod_alias;

// FIXME: do this right
	mod->mins[0] = mod->mins[1] = mod->mins[2] = -16;
	mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16;

	//
	// build the draw lists
	//
	GL_MakeAliasModelDisplayLists (mod, pheader);

//
// move the complete, relocatable alias model to the cache
//	
	end = Hunk_LowMark ();
	total = end - start;
	
	Cache_Alloc (&mod->cache, total, loadname);
	if (!mod->cache.data)
		return;
	memcpy (mod->cache.data, pheader, total);

	Hunk_FreeToLowMark (start);
}
Ejemplo n.º 3
0
bool idRenderModelMDL::Load( idList<byte>& buffer, idSkinTranslation* skinTranslation ) {
	mdl_t* pinmodel = ( mdl_t* )buffer.Ptr();

	int version = LittleLong( pinmodel->version );
	if ( version != MESH1_VERSION ) {
		common->FatalError( "%s has wrong version number (%i should be %i)",
			name, version, MESH1_VERSION );
	}

	//
	// allocate space for a working header, plus all the data except the frames,
	// skin and group info
	//
	mdl_pheader = new idSurfaceMDL;

	q1_flags = LittleLong( pinmodel->flags );

	//
	// endian-adjust and copy the data, starting with the alias model header
	//
	mdl_pheader->header.boundingradius = LittleFloat( pinmodel->boundingradius );
	mdl_pheader->header.numskins = LittleLong( pinmodel->numskins );
	mdl_pheader->header.skinwidth = LittleLong( pinmodel->skinwidth );
	mdl_pheader->header.skinheight = LittleLong( pinmodel->skinheight );

	if ( mdl_pheader->header.skinheight > MAX_LBM_HEIGHT ) {
		common->FatalError( "model %s has a skin taller than %d", name, MAX_LBM_HEIGHT );
	}

	mdl_pheader->header.numverts = LittleLong( pinmodel->numverts );

	if ( mdl_pheader->header.numverts <= 0 ) {
		common->FatalError( "model %s has no vertices", name );
	}

	if ( mdl_pheader->header.numverts > MAXALIASVERTS ) {
		common->FatalError( "model %s has too many vertices", name );
	}

	mdl_pheader->header.numtris = LittleLong( pinmodel->numtris );

	if ( mdl_pheader->header.numtris <= 0 ) {
		common->FatalError( "model %s has no mdl_triangles", name );
	}

	mdl_pheader->header.numframes = LittleLong( pinmodel->numframes );
	mdl_pheader->header.frames = new mmesh1framedesc_t[ mdl_pheader->header.numframes ];
	int numframes = mdl_pheader->header.numframes;
	if ( numframes < 1 ) {
		common->FatalError( "Mod_LoadMdlModel: Invalid # of frames: %d\n", numframes );
	}

	mdl_pheader->header.size = LittleFloat( pinmodel->size ) * ALIAS_BASE_SIZE_RATIO;
	q1_synctype = ( synctype_t )LittleLong( pinmodel->synctype );
	q1_numframes = mdl_pheader->header.numframes;

	for ( int i = 0; i < 3; i++ ) {
		mdl_pheader->header.scale[ i ] = LittleFloat( pinmodel->scale[ i ] );
		mdl_pheader->header.scale_origin[ i ] = LittleFloat( pinmodel->scale_origin[ i ] );
		mdl_pheader->header.eyeposition[ i ] = LittleFloat( pinmodel->eyeposition[ i ] );
	}

	//
	// load the skins
	//
	dmdl_skintype_t* pskintype = ( dmdl_skintype_t* )&pinmodel[ 1 ];
	pskintype = ( dmdl_skintype_t* )Mod_LoadAllSkins( mdl_pheader->header.numskins, pskintype, q1_flags, skinTranslation );

	//
	// load base s and t vertices
	//
	dmdl_stvert_t* pinstverts = ( dmdl_stvert_t* )pskintype;
	for ( int i = 0; i < mdl_pheader->header.numverts; i++ ) {
		mdl_stverts[ i ].onseam = LittleLong( pinstverts[ i ].onseam );
		mdl_stverts[ i ].s = LittleLong( pinstverts[ i ].s );
		mdl_stverts[ i ].t = LittleLong( pinstverts[ i ].t );
	}

	//
	// load triangle lists
	//
	dmdl_triangle_t* pintriangles = ( dmdl_triangle_t* )&pinstverts[ mdl_pheader->header.numverts ];

	for ( int i = 0; i < mdl_pheader->header.numtris; i++ ) {
		mdl_triangles[ i ].facesfront = LittleLong( pintriangles[ i ].facesfront );

		for ( int j = 0; j < 3; j++ ) {
			mdl_triangles[ i ].vertindex[ j ] = LittleLong( pintriangles[ i ].vertindex[ j ] );
			mdl_triangles[ i ].stindex[ j ]   = mdl_triangles[ i ].vertindex[ j ];
		}
	}

	//
	// load the frames
	//
	mdl_posenum = 0;
	dmdl_frametype_t* pframetype = ( dmdl_frametype_t* )&pintriangles[ mdl_pheader->header.numtris ];

	mdl_mins[ 0 ] = mdl_mins[ 1 ] = mdl_mins[ 2 ] = 32768;
	mdl_maxs[ 0 ] = mdl_maxs[ 1 ] = mdl_maxs[ 2 ] = -32768;

	for ( int i = 0; i < numframes; i++ ) {
		mdl_frametype_t frametype = ( mdl_frametype_t )LittleLong( pframetype->type );
		if ( frametype == ALIAS_SINGLE ) {
			pframetype = ( dmdl_frametype_t* )Mod_LoadAliasFrame( pframetype + 1, &mdl_pheader->header.frames[ i ] );
		} else {
			pframetype = ( dmdl_frametype_t* )Mod_LoadAliasGroup( pframetype + 1, &mdl_pheader->header.frames[ i ] );
		}
	}

	mdl_pheader->header.numposes = mdl_posenum;

	type = MOD_MESH1;

	// FIXME: do this right
	if ( GGameType & GAME_Hexen2 ) {
		q1_mins[ 0 ] = mdl_mins[ 0 ] - 10;
		q1_mins[ 1 ] = mdl_mins[ 1 ] - 10;
		q1_mins[ 2 ] = mdl_mins[ 2 ] - 10;
		q1_maxs[ 0 ] = mdl_maxs[ 0 ] + 10;
		q1_maxs[ 1 ] = mdl_maxs[ 1 ] + 10;
		q1_maxs[ 2 ] = mdl_maxs[ 2 ] + 10;
	} else {
		q1_mins[ 0 ] = q1_mins[ 1 ] = q1_mins[ 2 ] = -16;
		q1_maxs[ 0 ] = q1_maxs[ 1 ] = q1_maxs[ 2 ] = 16;
	}

	//
	// build the draw lists
	//
	GL_MakeAliasModelDisplayLists( this, mdl_pheader );

	q1_mdl = mdl_pheader;
	return true;
}
Ejemplo n.º 4
0
/*
=================
Mod_LoadAliasModel
=================
*/
void Mod_LoadAliasModel (model_t *mod, void *buffer)
{
	int					i, j;
	mdl_t				*pinmodel;
	stvert_t			*pinstverts;
	dtriangle_t			*pintriangles;
	int					version, numframes, numskins;
	int					size;
	daliasframetype_t	*pframetype;
	daliasskintype_t	*pskintype;
	int					start, end, total;
	
	start = Hunk_LowMark ();

	pinmodel = (mdl_t *)buffer;

	version = LittleLong (pinmodel->version);
	if (version != ALIAS_VERSION)
		Sys_Error ("%s has wrong version number (%i should be %i)",
				 mod->name, version, ALIAS_VERSION);

//
// allocate space for a working header, plus all the data except the frames,
// skin and group info
//
	size = 	sizeof (aliashdr_t) 
			+ (LittleLong (pinmodel->numframes) - 1) *
			sizeof (pheader->frames[0]);
	pheader = Hunk_AllocName (size, loadname);
	
	mod->flags = LittleLong (pinmodel->flags);

//
// endian-adjust and copy the data, starting with the alias model header
//
	pheader->boundingradius = LittleFloat (pinmodel->boundingradius);
	pheader->numskins = LittleLong (pinmodel->numskins);
	pheader->skinwidth = LittleLong (pinmodel->skinwidth);
	pheader->skinheight = LittleLong (pinmodel->skinheight);

	if (pheader->skinheight > MAX_LBM_HEIGHT)
		Sys_Error ("model %s has a skin taller than %d", mod->name,
				   MAX_LBM_HEIGHT);

	pheader->numverts = LittleLong (pinmodel->numverts);

	if (pheader->numverts <= 0)
		Sys_Error ("model %s has no vertices", mod->name);

	if (pheader->numverts > MAXALIASVERTS)
		Sys_Error ("model %s has too many vertices", mod->name);

	pheader->numtris = LittleLong (pinmodel->numtris);

	if (pheader->numtris <= 0)
		Sys_Error ("model %s has no triangles", mod->name);

	pheader->numframes = LittleLong (pinmodel->numframes);
	numframes = pheader->numframes;
	if (numframes < 1)
		Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes);

	pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
	mod->synctype = LittleLong (pinmodel->synctype);
	mod->numframes = pheader->numframes;

	for (i=0 ; i<3 ; i++)
	{
		pheader->scale[i] = LittleFloat (pinmodel->scale[i]);
		pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]);
		pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]);
	}


//
// load the skins
//
	pskintype = (daliasskintype_t *)&pinmodel[1];
	pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype);

//
// load base s and t vertices
//
	pinstverts = (stvert_t *)pskintype;

	for (i=0 ; i<pheader->numverts ; i++)
	{
		stverts[i].onseam = LittleLong (pinstverts[i].onseam);
		stverts[i].s = LittleLong (pinstverts[i].s);
		stverts[i].t = LittleLong (pinstverts[i].t);
	}

//
// load triangle lists
//
	pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts];

	for (i=0 ; i<pheader->numtris ; i++)
	{
		triangles[i].facesfront = LittleLong (pintriangles[i].facesfront);

		for (j=0 ; j<3 ; j++)
		{
			triangles[i].vertindex[j] =
					LittleLong (pintriangles[i].vertindex[j]);
		}
	}

//
// load the frames
//
	posenum = 0;
	pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris];

	for (i=0 ; i<numframes ; i++)
	{
		aliasframetype_t	frametype;

		frametype = LittleLong (pframetype->type);

		if (frametype == ALIAS_SINGLE)
		{
			pframetype = (daliasframetype_t *)
					Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]);
		}
		else
		{
			pframetype = (daliasframetype_t *)
					Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]);
		}
	}


	pheader->numposes = posenum;

	mod->type = mod_alias;

// FIXME: do this right
	mod->mins[0] = mod->mins[1] = mod->mins[2] = -16;
	mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16;
#if ALIAS_VBO
	///////////////////////////////////////////////////////////
	//
	//create a gl VBO object so we don't have to send this data each frame
	//
	//FORMAT [TEXTURE DATA BLOCK]
	//		 [VERTEX BLOCK FRAME 0]
	//		 [VERTEX BLOCK FRAME 1]
	//		 [VERTEX BLOCK FRAME 2]
	//		 ...
	//		 [VERTEX BLOCK FRAME N]
	//int numfloats = pheader->numposes * pheader->numtris * /*floats per verts*/ 9 * /*verts per triangle*/ 3;
	int numGLVerts = pheader->numposes * pheader->numtris * 3;
	
	glAliasData* gpuBoundData = (glAliasData*)malloc(sizeof(glAliasData)*numGLVerts);

	int processedIndex = 0;
	int f, t, v;
	for (f=0 ; f<pheader->numposes ; f++)
	{
		for (t = 0; t < pheader->numtris; t++)
		{
			for(v=0; v<3; v++){
				//
				int vIdx = triangles[t].vertindex[v];
				const trivertx_t* pVtx = &poseverts[f][vIdx];

				//pintriangles[t].facesfront;
				byte x = pVtx->v[0]; //render code applies scale + translation
				byte y = pVtx->v[1];
				byte z = pVtx->v[2];

				/* Compute texture coordinates */
				float cs = stverts[vIdx].s;
				float ct = stverts[vIdx].t;
				if (!triangles[t].facesfront && stverts[vIdx].onseam)
				{
					cs += pheader->skinwidth * 0.5f;
				}

				cs = (cs + 0.5f) / pheader->skinwidth;
				ct = (ct + 0.5f) / pheader->skinheight;

				gpuBoundData[processedIndex].st[0] = (unsigned char)(255 * cs);
				gpuBoundData[processedIndex].st[1] = (unsigned char)(255 * ct);

				//gpuBoundData[processedIndex].st[0] = cs;
				//gpuBoundData[processedIndex].st[1] = ct;

				gpuBoundData[processedIndex].pos[0] = x;
				gpuBoundData[processedIndex].pos[1] = y;
				gpuBoundData[processedIndex].pos[2] = z;

				gpuBoundData[processedIndex].lightNormalIndex = pVtx->lightnormalindex;
				processedIndex++;
			}
		}
	}

		CreatAliasBuffers(&pheader->vbo_offset,numGLVerts,gpuBoundData);

	free(gpuBoundData);

	//JAMES
	//we can brobably safely ditch most of what is below, just a waste of memory now
#endif //ALIAS_VBO
	
	///////////////////////////////////////////////////////////

	//
	// build the draw lists
	//
	GL_MakeAliasModelDisplayLists (mod, pheader);

//
// move the complete, relocatable alias model to the cache
//	
	end = Hunk_LowMark ();
	total = end - start;
	
	Cache_Alloc (&mod->cache, total, loadname);
	if (!mod->cache.data)
		return;
	memcpy (mod->cache.data, pheader, total);

	Hunk_FreeToLowMark (start);
}
Ejemplo n.º 5
0
/*
=================
Mod_LoadAliasModel
=================
*/
void
Mod_LoadAliasModel(const model_loader_t *loader, model_t *mod, void *buffer,
		   const model_t *loadmodel, const char *loadname)
{
   byte *container;
   int i, j, pad;
   mdl_t *pinmodel;
   stvert_t *pinstverts;
   dtriangle_t *pintriangles;
   int version, numframes;
   int size;
   daliasframetype_t *pframetype;
   daliasframe_t *frame;
   daliasgroup_t *group;
   daliasskintype_t *pskintype;
   int start, end, total;
   float *intervals;

#ifdef QW_HACK
   const char *crcmodel = NULL;
   if (!strcmp(loadmodel->name, "progs/player.mdl"))
      crcmodel = "pmodel";
   if (!strcmp(loadmodel->name, "progs/eyes.mdl"))
      crcmodel = "emodel";

   if (crcmodel)
   {
      uint16_t crc = CRC_Block(buffer, com_filesize);
      Info_SetValueForKey(cls.userinfo, crcmodel, va("%d", (int)crc),
            MAX_INFO_STRING);

      if (cls.state >= ca_connected)
      {
         MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
         MSG_WriteStringf(&cls.netchan.message, "setinfo %s %d", crcmodel,
               (int)crc);
      }
   }
#endif

   start = Hunk_LowMark();

   pinmodel = (mdl_t *)buffer;

#ifdef MSB_FIRST
   version = LittleLong(pinmodel->version);
#else
   version = (pinmodel->version);
#endif
   if (version != ALIAS_VERSION)
      Sys_Error("%s has wrong version number (%i should be %i)",
            mod->name, version, ALIAS_VERSION);

   // allocate space for a working header, plus all the data except the frames,
   // skin and group info
   pad = loader->Aliashdr_Padding();
#ifdef MSB_FIRST
   size = pad + sizeof(aliashdr_t) +
      LittleLong(pinmodel->numframes) * sizeof(pheader->frames[0]);
#else
   size = pad + sizeof(aliashdr_t) +
      (pinmodel->numframes) * sizeof(pheader->frames[0]);
#endif

   container = (byte*)Hunk_AllocName(size, loadname);
   pheader = (aliashdr_t *)(container + pad);

#ifdef MSB_FIRST
   mod->flags = LittleLong(pinmodel->flags);

   // endian-adjust and copy the data, starting with the alias model header
   pheader->numskins = LittleLong(pinmodel->numskins);
   pheader->skinwidth = LittleLong(pinmodel->skinwidth);
   pheader->skinheight = LittleLong(pinmodel->skinheight);
#else
   mod->flags = (pinmodel->flags);

   pheader->numskins = (pinmodel->numskins);
   pheader->skinwidth = (pinmodel->skinwidth);
   pheader->skinheight = (pinmodel->skinheight);
#endif


   if (pheader->skinheight > MAX_LBM_HEIGHT)
      Sys_Error("model %s has a skin taller than %d", mod->name,
            MAX_LBM_HEIGHT);

#ifdef MSB_FIRST
   pheader->numverts = LittleLong(pinmodel->numverts);
#else
   pheader->numverts = (pinmodel->numverts);
#endif

   if (pheader->numverts <= 0)
      Sys_Error("model %s has no vertices", mod->name);

   if (pheader->numverts > MAXALIASVERTS)
      Sys_Error("model %s has too many vertices", mod->name);

#ifdef MSB_FIRST
   pheader->numtris = LittleLong(pinmodel->numtris);
#else
   pheader->numtris = (pinmodel->numtris);
#endif

   if (pheader->numtris <= 0)
      Sys_Error("model %s has no triangles", mod->name);

#ifdef MSB_FIRST
   pheader->numframes = LittleLong(pinmodel->numframes);
   pheader->size = LittleFloat(pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
   mod->synctype = (synctype_t)LittleLong(pinmodel->synctype);
#else
   pheader->numframes = (pinmodel->numframes);
   pheader->size = (pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
   mod->synctype = (synctype_t)(pinmodel->synctype);
#endif
   mod->numframes = pheader->numframes;

   for (i = 0; i < 3; i++) {
#ifdef MSB_FIRST
      pheader->scale[i] = LittleFloat(pinmodel->scale[i]);
      pheader->scale_origin[i] = LittleFloat(pinmodel->scale_origin[i]);
#else
      pheader->scale[i] = (pinmodel->scale[i]);
      pheader->scale_origin[i] = (pinmodel->scale_origin[i]);
#endif
   }

   // load the skins
   pskintype = (daliasskintype_t *)&pinmodel[1];
   pskintype = (daliasskintype_t *)Mod_LoadAllSkins(loader, loadmodel, pheader->numskins,
         pskintype, loadname);

   // set base s and t vertices
   pinstverts = (stvert_t *)pskintype;
   for (i = 0; i < pheader->numverts; i++) {
#ifdef MSB_FIRST
      stverts[i].onseam = LittleLong(pinstverts[i].onseam);
      stverts[i].s = LittleLong(pinstverts[i].s);
      stverts[i].t = LittleLong(pinstverts[i].t);
#else
      stverts[i].onseam = (pinstverts[i].onseam);
      stverts[i].s = (pinstverts[i].s);
      stverts[i].t = (pinstverts[i].t);
#endif
   }

   // set up the triangles
   pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts];
   for (i = 0; i < pheader->numtris; i++)
   {
#ifdef MSB_FIRST
      triangles[i].facesfront = LittleLong(pintriangles[i].facesfront);
#else
      triangles[i].facesfront = (pintriangles[i].facesfront);
#endif
      for (j = 0; j < 3; j++)
      {
#ifdef MSB_FIRST
         triangles[i].vertindex[j] = LittleLong(pintriangles[i].vertindex[j]);
#else
         triangles[i].vertindex[j] = (pintriangles[i].vertindex[j]);
#endif
         if (triangles[i].vertindex[j] < 0 ||
               triangles[i].vertindex[j] >= pheader->numverts)
            Sys_Error("%s: invalid vertex index (%d of %d) in %s\n",
                  __func__, triangles[i].vertindex[j],
                  pheader->numverts, mod->name);
      }
   }

   /* load the frames */
   numframes = pheader->numframes;
   if (numframes < 1)
      Sys_Error("%s: Invalid # of frames: %d", __func__, numframes);

   posenum = 0;
   pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris];

   for (i = 0; i < numframes; i++)
   {
#ifdef MSB_FIRST
      if (LittleLong(pframetype->type) == ALIAS_SINGLE)
#else
         if ((pframetype->type) == ALIAS_SINGLE)
#endif
         {
            frame = (daliasframe_t *)(pframetype + 1);
            Mod_LoadAliasFrame(frame, &pheader->frames[i]);
            pframetype = (daliasframetype_t *)&frame->verts[pheader->numverts];
         } else {
            group = (daliasgroup_t *)(pframetype + 1);
            pframetype = Mod_LoadAliasGroup(group, &pheader->frames[i],
                  loadname);
         }
   }
   pheader->numposes = posenum;
   mod->type = mod_alias;

   // FIXME: do this right
   mod->mins[0] = mod->mins[1] = mod->mins[2] = -16;
   mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16;

   /* Save the frame intervals */
   intervals = (float*)Hunk_Alloc(pheader->numposes * sizeof(float));
   pheader->poseintervals = (byte *)intervals - (byte *)pheader;
   for (i = 0; i < pheader->numposes; i++)
      intervals[i] = poseintervals[i];

   /* Save the mesh data (verts, stverts, triangles) */
   loader->LoadMeshData(loadmodel, pheader, triangles, stverts, poseverts);

   // move the complete, relocatable alias model to the cache
   end = Hunk_LowMark();
   total = end - start;

   Cache_AllocPadded(&mod->cache, pad, total - pad, loadname);
   if (!mod->cache.data)
      return;

   memcpy((byte *)mod->cache.data - pad, container, total);

   Hunk_FreeToLowMark(start);
}