Ejemplo n.º 1
0
static void ModelCallback (void *unused)
{
	char scratch[MAX_QPATH];

	s_player_skin_box.itemnames = s_pmi[s_player_model_box.curvalue].skindisplaynames;
	s_player_skin_box.curvalue = 0;

	// only register model and skin on starup or when changed
	Com_sprintf( scratch, sizeof(scratch), "players/%s/tris.md2", s_pmi[s_player_model_box.curvalue].directory );
	playermodel = R_RegisterModel (scratch);

	Com_sprintf( scratch, sizeof(scratch), "players/%s/%s.pcx", s_pmi[s_player_model_box.curvalue].directory, s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue] );
	playerskin = R_RegisterSkin (scratch);

	// show current weapon model (if any)
	if (currentweaponmodel && strlen(currentweaponmodel)) {
		Com_sprintf (scratch, sizeof(scratch), "players/%s/%s", s_pmi[s_player_model_box.curvalue].directory, currentweaponmodel);
		weaponmodel = R_RegisterModel(scratch);
		if (!weaponmodel) {
			Com_sprintf (scratch, sizeof(scratch), "players/%s/weapon.md2", s_pmi[s_player_model_box.curvalue].directory);
			weaponmodel = R_RegisterModel (scratch);
		}
	}
	else {
		Com_sprintf (scratch, sizeof(scratch), "players/%s/weapon.md2", s_pmi[s_player_model_box.curvalue].directory);
		weaponmodel = R_RegisterModel (scratch);
	}
}
Ejemplo n.º 2
0
// only register skin on starup and when changed
static void SkinCallback (void *unused)
{
	char scratch[MAX_QPATH];

	Com_sprintf(scratch, sizeof(scratch), "players/%s/%s.pcx", s_pmi[s_player_model_box.curvalue].directory, s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue]);
	playerskin = R_RegisterSkin(scratch);
}
Ejemplo n.º 3
0
/*
* SkinFile_ParseBuffer
*/
static int SkinFile_ParseBuffer( char *buffer, mesh_shader_pair_t *pairs )
{
	int numpairs;
	char *ptr, *t, *token;

	ptr = buffer;
	numpairs = 0;

	while( ptr )
	{
		token = COM_ParseExt( &ptr, qfalse );
		if( !token[0] )
			continue;

		t = strchr( token, ',' );
		if( !t )
			continue;
		if( *( t+1 ) == '\0' || *( t+1 ) == '\n' )
			continue;

		if( pairs )
		{
			*t = 0;
			pairs[numpairs].meshname = SkinFile_CopyString( token );
			pairs[numpairs].shader = R_RegisterSkin( token + strlen( token ) + 1 );
		}

		numpairs++;
	}

	return numpairs;
}
Ejemplo n.º 4
0
void QCBUILTIN PF_shaderforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
	const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
	const char *defaultbody = PF_VarString(prinst, 1, pr_globals);

	shader_t *shad;

	if (*defaultbody)
		shad = R_RegisterShader(str, SUF_NONE, defaultbody);
	else
		shad = R_RegisterSkin(str, NULL);
	if (shad)
		G_FLOAT(OFS_RETURN) = shad->id+1;
	else
		G_FLOAT(OFS_RETURN) = 0;
}
Ejemplo n.º 5
0
/*
================
CL_LoadClientinfo

================
*/
void CL_LoadClientinfo (clientinfo_t *ci, char *s)
{
	int32_t i;
	char		*t;
	char		model_name[MAX_QPATH];
	char		skin_name[MAX_QPATH];
	char		model_filename[MAX_QPATH];
	char		skin_filename[MAX_QPATH];
	char		weapon_filename[MAX_QPATH];

	strncpy(ci->cinfo, s, sizeof(ci->cinfo));
	ci->cinfo[sizeof(ci->cinfo)-1] = 0;

	// isolate the player's name
	strncpy(ci->name, s, sizeof(ci->name));
	ci->name[sizeof(ci->name)-1] = 0;
	t = strstr (s, "\\");
	if (t)
	{
		ci->name[t-s] = 0;
		s = t+1;
	}

	if (cl_noskins->value || *s == 0)
	{
		Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");
		Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/male/weapon.md2");
		Com_sprintf (skin_filename, sizeof(skin_filename), "players/male/grunt.pcx");
		Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/male/grunt_i.pcx");
		ci->model = R_RegisterModel (model_filename);
		memset(ci->weaponmodel, 0, sizeof(ci->weaponmodel));
		ci->weaponmodel[0] = R_RegisterModel (weapon_filename);
		ci->skin = R_RegisterSkin (skin_filename);
		ci->icon = R_DrawFindPic (ci->iconname);
	}
	else
	{
		// isolate the model name
		strcpy (model_name, s);
		t = strstr(model_name, "/");
		if (!t)
			t = strstr(model_name, "\\");
		if (!t)
			t = model_name;
		*t = 0;

		// isolate the skin name
		strcpy (skin_name, s + strlen(model_name) + 1);

		// model file
		Com_sprintf (model_filename, sizeof(model_filename), "players/%s/tris.md2", model_name);
		ci->model = R_RegisterModel (model_filename);
		if (!ci->model)
		{
			strcpy(model_name, "male");
			Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");
			ci->model = R_RegisterModel (model_filename);
		}

		// skin file
		Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);
		ci->skin = R_RegisterSkin (skin_filename);

		// if we don't have the skin and the model wasn't male,
		// see if the male has it (this is for CTF's skins)
 		if (!ci->skin && Q_strcasecmp(model_name, "male"))
		{
			// change model to male
			strcpy(model_name, "male");
			Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");
			ci->model = R_RegisterModel (model_filename);

			// see if the skin exists for the male model
			Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);
			ci->skin = R_RegisterSkin (skin_filename);
		}

		// if we still don't have a skin, it means that the male model didn't have
		// it, so default to grunt
		if (!ci->skin) {
			// see if the skin exists for the male model
			Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/grunt.pcx", model_name, skin_name);
			ci->skin = R_RegisterSkin (skin_filename);
		}

		// weapon file
		for (i = 0; i < num_cl_weaponmodels; i++) {
			Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/%s/%s", model_name, cl_weaponmodels[i]);
			ci->weaponmodel[i] = R_RegisterModel(weapon_filename);
			if (!ci->weaponmodel[i] && strcmp(model_name, "cyborg") == 0) {
				// try male
				Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/male/%s", cl_weaponmodels[i]);
				ci->weaponmodel[i] = R_RegisterModel(weapon_filename);
			}
			if (!cl_vwep->value)
				break; // only one when vwep is off
		}

		// icon file
		Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/%s/%s_i.pcx", model_name, skin_name);
		ci->icon = R_DrawFindPic (ci->iconname);
	}

	// must have loaded all data types to be valud
	if (!ci->skin || !ci->icon || !ci->model || !ci->weaponmodel[0])
	{
		ci->skin = NULL;
		ci->icon = NULL;
		ci->model = NULL;
		ci->weaponmodel[0] = NULL;
		return;
	}
}
Ejemplo n.º 6
0
//	The cgame module is making a system call
qintptr CLWS_CgameSystemCalls( qintptr* args ) {
	switch ( args[ 0 ] ) {
	case WSCG_PRINT:
		common->Printf( "%s", ( char* )VMA( 1 ) );
		return 0;
	case WSCG_ERROR:
		common->Error( "%s", ( char* )VMA( 1 ) );
		return 0;
	case WSCG_MILLISECONDS:
		return Sys_Milliseconds();
	case WSCG_CVAR_REGISTER:
		Cvar_Register( ( vmCvar_t* )VMA( 1 ), ( char* )VMA( 2 ), ( char* )VMA( 3 ), args[ 4 ] );
		return 0;
	case WSCG_CVAR_UPDATE:
		Cvar_Update( ( vmCvar_t* )VMA( 1 ) );
		return 0;
	case WSCG_CVAR_SET:
		Cvar_Set( ( char* )VMA( 1 ), ( char* )VMA( 2 ) );
		return 0;
	case WSCG_CVAR_VARIABLESTRINGBUFFER:
		Cvar_VariableStringBuffer( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] );
		return 0;
	case WSCG_ARGC:
		return Cmd_Argc();
	case WSCG_ARGV:
		Cmd_ArgvBuffer( args[ 1 ], ( char* )VMA( 2 ), args[ 3 ] );
		return 0;
	case WSCG_ARGS:
		Cmd_ArgsBuffer( ( char* )VMA( 1 ), args[ 2 ] );
		return 0;
	case WSCG_FS_FOPENFILE:
		return FS_FOpenFileByMode( ( char* )VMA( 1 ), ( fileHandle_t* )VMA( 2 ), ( fsMode_t )args[ 3 ] );
	case WSCG_FS_READ:
		FS_Read( VMA( 1 ), args[ 2 ], args[ 3 ] );
		return 0;
	case WSCG_FS_WRITE:
		return FS_Write( VMA( 1 ), args[ 2 ], args[ 3 ] );
	case WSCG_FS_FCLOSEFILE:
		FS_FCloseFile( args[ 1 ] );
		return 0;
	case WSCG_SENDCONSOLECOMMAND:
		Cbuf_AddText( ( char* )VMA( 1 ) );
		return 0;
	case WSCG_ADDCOMMAND:
		CLT3_AddCgameCommand( ( char* )VMA( 1 ) );
		return 0;
	case WSCG_REMOVECOMMAND:
		Cmd_RemoveCommand( ( char* )VMA( 1 ) );
		return 0;
	case WSCG_SENDCLIENTCOMMAND:
		CL_AddReliableCommand( ( char* )VMA( 1 ) );
		return 0;
	case WSCG_UPDATESCREEN:
		SCR_UpdateScreen();
		return 0;
	case WSCG_CM_LOADMAP:
		CLT3_CM_LoadMap( ( char* )VMA( 1 ) );
		return 0;
	case WSCG_CM_NUMINLINEMODELS:
		return CM_NumInlineModels();
	case WSCG_CM_INLINEMODEL:
		return CM_InlineModel( args[ 1 ] );
	case WSCG_CM_TEMPBOXMODEL:
		return CM_TempBoxModel( ( float* )VMA( 1 ), ( float* )VMA( 2 ), false );
	case WSCG_CM_TEMPCAPSULEMODEL:
		return CM_TempBoxModel( ( float* )VMA( 1 ), ( float* )VMA( 2 ), true );
	case WSCG_CM_POINTCONTENTS:
		return CM_PointContentsQ3( ( float* )VMA( 1 ), args[ 2 ] );
	case WSCG_CM_TRANSFORMEDPOINTCONTENTS:
		return CM_TransformedPointContentsQ3( ( float* )VMA( 1 ), args[ 2 ], ( float* )VMA( 3 ), ( float* )VMA( 4 ) );
	case WSCG_CM_BOXTRACE:
		CM_BoxTraceQ3( ( q3trace_t* )VMA( 1 ), ( float* )VMA( 2 ), ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ), args[ 6 ], args[ 7 ], false );
		return 0;
	case WSCG_CM_TRANSFORMEDBOXTRACE:
		CM_TransformedBoxTraceQ3( ( q3trace_t* )VMA( 1 ), ( float* )VMA( 2 ), ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ), args[ 6 ], args[ 7 ], ( float* )VMA( 8 ), ( float* )VMA( 9 ), false );
		return 0;
	case WSCG_CM_CAPSULETRACE:
		CM_BoxTraceQ3( ( q3trace_t* )VMA( 1 ), ( float* )VMA( 2 ), ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ), args[ 6 ], args[ 7 ], true );
		return 0;
	case WSCG_CM_TRANSFORMEDCAPSULETRACE:
		CM_TransformedBoxTraceQ3( ( q3trace_t* )VMA( 1 ), ( float* )VMA( 2 ), ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ), args[ 6 ], args[ 7 ], ( float* )VMA( 8 ), ( float* )VMA( 9 ), true );
		return 0;
	case WSCG_CM_MARKFRAGMENTS:
		return R_MarkFragmentsWolf( args[ 1 ], ( const vec3_t* )VMA( 2 ), ( float* )VMA( 3 ), args[ 4 ], ( float* )VMA( 5 ), args[ 6 ], ( markFragment_t* )VMA( 7 ) );
	case WSCG_S_STARTSOUND:
		S_StartSound( ( float* )VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ], 0.5 );
		return 0;
	case WSCG_S_STARTSOUNDEX:
		S_StartSoundEx( ( float* )VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ], 127 );
		return 0;
	case WSCG_S_STARTLOCALSOUND:
		S_StartLocalSound( args[ 1 ], args[ 2 ], 127 );
		return 0;
	case WSCG_S_CLEARLOOPINGSOUNDS:
		CLWS_ClearLoopingSounds( args[ 1 ] );
		return 0;
	case WSCG_S_ADDLOOPINGSOUND:
		// FIXME MrE: handling of looping sounds changed
		S_AddLoopingSound( args[ 1 ], ( float* )VMA( 2 ), ( float* )VMA( 3 ), args[ 4 ], args[ 5 ], args[ 6 ], 0 );
		return 0;
	case WSCG_S_STOPSTREAMINGSOUND:
		S_StopEntStreamingSound( args[ 1 ] );
		return 0;
	case WSCG_S_STOPLOOPINGSOUND:
		// RF, not functional anymore, since we reverted to old looping code
		return 0;
	case WSCG_S_UPDATEENTITYPOSITION:
		S_UpdateEntityPosition( args[ 1 ], ( float* )VMA( 2 ) );
		return 0;
	case WSCG_S_GETVOICEAMPLITUDE:
		return S_GetVoiceAmplitude( args[ 1 ] );
	case WSCG_S_RESPATIALIZE:
		S_Respatialize( args[ 1 ], ( float* )VMA( 2 ), ( vec3_t* )VMA( 3 ), args[ 4 ] );
		return 0;
	case WSCG_S_REGISTERSOUND:
		return S_RegisterSound( ( char* )VMA( 1 ) );
	case WSCG_S_STARTBACKGROUNDTRACK:
		S_StartBackgroundTrack( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] );			//----(SA)	added fadeup time
		return 0;
	case WSCG_S_FADESTREAMINGSOUND:
		S_FadeStreamingSound( VMF( 1 ), args[ 2 ], args[ 3 ] );		//----(SA)	added music/all-streaming options
		return 0;
	case WSCG_S_STARTSTREAMINGSOUND:
		S_StartStreamingSound( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ], args[ 4 ], args[ 5 ] );
		return 0;
	case WSCG_S_FADEALLSOUNDS:
		S_FadeAllSounds( VMF( 1 ), args[ 2 ], false );			//----(SA)	added
		return 0;
	case WSCG_R_LOADWORLDMAP:
		R_LoadWorld( ( char* )VMA( 1 ) );
		return 0;
	case WSCG_R_REGISTERMODEL:
		return R_RegisterModel( ( char* )VMA( 1 ) );
	case WSCG_R_REGISTERSKIN:
		return R_RegisterSkin( ( char* )VMA( 1 ) );
	case WSCG_R_GETSKINMODEL:
		return R_GetSkinModel( args[ 1 ], ( char* )VMA( 2 ), ( char* )VMA( 3 ) );
	case WSCG_R_GETMODELSHADER:
		return R_GetShaderFromModel( args[ 1 ], args[ 2 ], args[ 3 ] );
	case WSCG_R_REGISTERSHADER:
		return R_RegisterShader( ( char* )VMA( 1 ) );
	case WSCG_R_REGISTERFONT:
		R_RegisterFont( ( char* )VMA( 1 ), args[ 2 ], ( fontInfo_t* )VMA( 3 ) );
	case WSCG_R_REGISTERSHADERNOMIP:
		return R_RegisterShaderNoMip( ( char* )VMA( 1 ) );
	case WSCG_R_CLEARSCENE:
		R_ClearScene();
		return 0;
	case WSCG_R_ADDREFENTITYTOSCENE:
		CLWS_AddRefEntityToScene( ( wsrefEntity_t* )VMA( 1 ) );
		return 0;
	case WSCG_R_ADDPOLYTOSCENE:
		R_AddPolyToScene( args[ 1 ], args[ 2 ], ( polyVert_t* )VMA( 3 ), 1 );
		return 0;
	case WSCG_R_ADDPOLYSTOSCENE:
		R_AddPolyToScene( args[ 1 ], args[ 2 ], ( polyVert_t* )VMA( 3 ), args[ 4 ] );
		return 0;
	case WSCG_RB_ZOMBIEFXADDNEWHIT:
		return 0;
	case WSCG_R_ADDLIGHTTOSCENE:
		R_AddLightToScene( ( float* )VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[ 6 ] );
		return 0;
	case WSCG_R_ADDCORONATOSCENE:
		R_AddCoronaToScene( ( float* )VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[ 6 ], args[ 7 ] );
		return 0;
	case WSCG_R_SETFOG:
		R_SetFog( args[ 1 ], args[ 2 ], args[ 3 ], VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ) );
		return 0;
	case WSCG_R_RENDERSCENE:
		CLWS_RenderScene( ( wsrefdef_t* )VMA( 1 ) );
		return 0;
	case WSCG_R_SETCOLOR:
		R_SetColor( ( float* )VMA( 1 ) );
		return 0;
	case WSCG_R_DRAWSTRETCHPIC:
		R_StretchPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[ 9 ] );
		return 0;
	case WSCG_R_DRAWSTRETCHPIC_GRADIENT:
		R_StretchPicGradient( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[ 9 ], ( float* )VMA( 10 ), args[ 11 ] );
		return 0;
	case WSCG_R_MODELBOUNDS:
		R_ModelBounds( args[ 1 ], ( float* )VMA( 2 ), ( float* )VMA( 3 ) );
		return 0;
	case WSCG_R_LERPTAG:
		return CLWS_LerpTag( ( orientation_t* )VMA( 1 ), ( wsrefEntity_t* )VMA( 2 ), ( char* )VMA( 3 ), args[ 4 ] );
	case WSCG_GETGLCONFIG:
		CLWS_GetGlconfig( ( wsglconfig_t* )VMA( 1 ) );
		return 0;
	case WSCG_GETGAMESTATE:
		CLWS_GetGameState( ( wsgameState_t* )VMA( 1 ) );
		return 0;
	case WSCG_GETCURRENTSNAPSHOTNUMBER:
		CLWS_GetCurrentSnapshotNumber( ( int* )VMA( 1 ), ( int* )VMA( 2 ) );
		return 0;
	case WSCG_GETSNAPSHOT:
		return CLWS_GetSnapshot( args[ 1 ], ( wssnapshot_t* )VMA( 2 ) );
	case WSCG_GETSERVERCOMMAND:
		return CLT3_GetServerCommand( args[ 1 ] );
	case WSCG_GETCURRENTCMDNUMBER:
		return CLT3_GetCurrentCmdNumber();
	case WSCG_GETUSERCMD:
		return CLWS_GetUserCmd( args[ 1 ], ( wsusercmd_t* )VMA( 2 ) );
	case WSCG_SETUSERCMDVALUE:
		CLWS_SetUserCmdValue( args[ 1 ], args[ 2 ], VMF( 3 ), args[ 4 ] );				//----(SA)	modified	// NERVE - SMF - added fourth arg [cld]
		return 0;
	case WSCG_MEMORY_REMAINING:
		return 0x4000000;
	case WSCG_KEY_ISDOWN:
		return Key_IsDown( args[ 1 ] );
	case WSCG_KEY_GETCATCHER:
		return Key_GetCatcher();
	case WSCG_KEY_SETCATCHER:
		KeyQ3_SetCatcher( args[ 1 ] );
		return 0;
	case WSCG_KEY_GETKEY:
		return Key_GetKey( ( char* )VMA( 1 ) );

	case WSCG_MEMSET:
		return ( qintptr )memset( VMA( 1 ), args[ 2 ], args[ 3 ] );
	case WSCG_MEMCPY:
		return ( qintptr )memcpy( VMA( 1 ), VMA( 2 ), args[ 3 ] );
	case WSCG_STRNCPY:
		String::NCpy( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] );
		return args[ 1 ];
	case WSCG_SIN:
		return FloatAsInt( sin( VMF( 1 ) ) );
	case WSCG_COS:
		return FloatAsInt( cos( VMF( 1 ) ) );
	case WSCG_ATAN2:
		return FloatAsInt( atan2( VMF( 1 ), VMF( 2 ) ) );
	case WSCG_SQRT:
		return FloatAsInt( sqrt( VMF( 1 ) ) );
	case WSCG_FLOOR:
		return FloatAsInt( floor( VMF( 1 ) ) );
	case WSCG_CEIL:
		return FloatAsInt( ceil( VMF( 1 ) ) );
	case WSCG_ACOS:
		return FloatAsInt( idMath::ACos( VMF( 1 ) ) );

	case WSCG_PC_ADD_GLOBAL_DEFINE:
		return PC_AddGlobalDefine( ( char* )VMA( 1 ) );
	case WSCG_PC_LOAD_SOURCE:
		return PC_LoadSourceHandle( ( char* )VMA( 1 ) );
	case WSCG_PC_FREE_SOURCE:
		return PC_FreeSourceHandle( args[ 1 ] );
	case WSCG_PC_READ_TOKEN:
		return PC_ReadTokenHandleQ3( args[ 1 ], ( q3pc_token_t* )VMA( 2 ) );
	case WSCG_PC_SOURCE_FILE_AND_LINE:
		return PC_SourceFileAndLine( args[ 1 ], ( char* )VMA( 2 ), ( int* )VMA( 3 ) );

	case WSCG_S_STOPBACKGROUNDTRACK:
		S_StopBackgroundTrack();
		return 0;

	case WSCG_REAL_TIME:
		return Com_RealTime( ( qtime_t* )VMA( 1 ) );
	case WSCG_SNAPVECTOR:
		Sys_SnapVector( ( float* )VMA( 1 ) );
		return 0;

	case WSCG_SENDMOVESPEEDSTOGAME:
		SVWS_SendMoveSpeedsToGame( args[ 1 ], ( char* )VMA( 2 ) );
		return 0;

	case WSCG_CIN_PLAYCINEMATIC:
		return CIN_PlayCinematicStretched( ( char* )VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ], args[ 6 ] );
	case WSCG_CIN_STOPCINEMATIC:
		return CIN_StopCinematic( args[ 1 ] );
	case WSCG_CIN_RUNCINEMATIC:
		return CIN_RunCinematic( args[ 1 ] );
	case WSCG_CIN_DRAWCINEMATIC:
		CIN_DrawCinematic( args[ 1 ] );
		return 0;
	case WSCG_CIN_SETEXTENTS:
		CIN_SetExtents( args[ 1 ], args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ] );
		return 0;

	case WSCG_R_REMAP_SHADER:
		R_RemapShader( ( char* )VMA( 1 ), ( char* )VMA( 2 ), ( char* )VMA( 3 ) );
		return 0;

	case WSCG_TESTPRINTINT:
		common->Printf( "%s%i\n", ( char* )VMA( 1 ), static_cast<int>( args[ 2 ] ) );
		return 0;
	case WSCG_TESTPRINTFLOAT:
		common->Printf( "%s%f\n", ( char* )VMA( 1 ), VMF( 2 ) );
		return 0;

	case WSCG_LOADCAMERA:
		return loadCamera( args[ 1 ], ( char* )VMA( 2 ) );
	case WSCG_STARTCAMERA:
		CLWS_StartCamera( args[ 1 ], args[ 2 ] );
		return 0;
	case WSCG_STOPCAMERA:
		CLWS_StopCamera( args[ 1 ] );
		return 0;
	case WSCG_GETCAMERAINFO:
		return getCameraInfo( args[ 1 ], args[ 2 ], ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ) );

	case WSCG_GET_ENTITY_TOKEN:
		return R_GetEntityToken( ( char* )VMA( 1 ), args[ 2 ] );

	case WSCG_INGAME_POPUP:
		CLWS_InGamePopup( ( char* )VMA( 1 ) );
		return 0;

	case WSCG_INGAME_CLOSEPOPUP:
		UIT3_KeyEvent( K_ESCAPE, true );
		return 0;

	case WSCG_LIMBOCHAT:
		CLT3_AddToLimboChat( ( char* )VMA( 1 ) );
		return 0;

	case WSCG_GETMODELINFO:
		return SVWS_GetModelInfo( args[ 1 ], ( char* )VMA( 2 ), ( animModelInfo_t** )VMA( 3 ) );

	default:
		common->Error( "Bad cgame system trap: %i", static_cast<int>( args[ 0 ] ) );
	}
	return 0;
}
Ejemplo n.º 7
0
//	The ui module is making a system call
qintptr CLWM_UISystemCalls( qintptr* args ) {
	switch ( args[ 0 ] ) {
	case WMUI_ERROR:
		common->Error( "%s", ( char* )VMA( 1 ) );
		return 0;

	case WMUI_PRINT:
		common->Printf( "%s", ( char* )VMA( 1 ) );
		return 0;

	case WMUI_MILLISECONDS:
		return Sys_Milliseconds();

	case WMUI_CVAR_REGISTER:
		Cvar_Register( ( vmCvar_t* )VMA( 1 ), ( char* )VMA( 2 ), ( char* )VMA( 3 ), args[ 4 ] );
		return 0;

	case WMUI_CVAR_UPDATE:
		Cvar_Update( ( vmCvar_t* )VMA( 1 ) );
		return 0;

	case WMUI_CVAR_SET:
		Cvar_Set( ( char* )VMA( 1 ), ( char* )VMA( 2 ) );
		return 0;

	case WMUI_CVAR_VARIABLEVALUE:
		return FloatAsInt( Cvar_VariableValue( ( char* )VMA( 1 ) ) );

	case WMUI_CVAR_VARIABLESTRINGBUFFER:
		Cvar_VariableStringBuffer( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] );
		return 0;

	case WMUI_CVAR_SETVALUE:
		Cvar_SetValue( ( char* )VMA( 1 ), VMF( 2 ) );
		return 0;

	case WMUI_CVAR_RESET:
		Cvar_Reset( ( char* )VMA( 1 ) );
		return 0;

	case WMUI_CVAR_CREATE:
		Cvar_Get( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] );
		return 0;

	case WMUI_CVAR_INFOSTRINGBUFFER:
		Cvar_InfoStringBuffer( args[ 1 ], MAX_INFO_STRING_Q3, ( char* )VMA( 2 ), args[ 3 ] );
		return 0;

	case WMUI_ARGC:
		return Cmd_Argc();

	case WMUI_ARGV:
		Cmd_ArgvBuffer( args[ 1 ], ( char* )VMA( 2 ), args[ 3 ] );
		return 0;

	case WMUI_CMD_EXECUTETEXT:
		Cbuf_ExecuteText( args[ 1 ], ( char* )VMA( 2 ) );
		return 0;

	case WMUI_FS_FOPENFILE:
		return FS_FOpenFileByMode( ( char* )VMA( 1 ), ( fileHandle_t* )VMA( 2 ), ( fsMode_t )args[ 3 ] );

	case WMUI_FS_READ:
		FS_Read( VMA( 1 ), args[ 2 ], args[ 3 ] );
		return 0;

	case WMUI_FS_WRITE:
		FS_Write( VMA( 1 ), args[ 2 ], args[ 3 ] );
		return 0;

	case WMUI_FS_FCLOSEFILE:
		FS_FCloseFile( args[ 1 ] );
		return 0;

	case WMUI_FS_DELETEFILE:
		return FS_Delete( ( char* )VMA( 1 ) );

	case WMUI_FS_GETFILELIST:
		return FS_GetFileList( ( char* )VMA( 1 ), ( char* )VMA( 2 ), ( char* )VMA( 3 ), args[ 4 ] );

	case WMUI_R_REGISTERMODEL:
		return R_RegisterModel( ( char* )VMA( 1 ) );

	case WMUI_R_REGISTERSKIN:
		return R_RegisterSkin( ( char* )VMA( 1 ) );

	case WMUI_R_REGISTERSHADERNOMIP:
		return R_RegisterShaderNoMip( ( char* )VMA( 1 ) );

	case WMUI_R_CLEARSCENE:
		R_ClearScene();
		return 0;

	case WMUI_R_ADDREFENTITYTOSCENE:
		CLWM_AddRefEntityToScene( ( wmrefEntity_t* )VMA( 1 ) );
		return 0;

	case WMUI_R_ADDPOLYTOSCENE:
		R_AddPolyToScene( args[ 1 ], args[ 2 ], ( polyVert_t* )VMA( 3 ), 1 );
		return 0;

	case WMUI_R_ADDPOLYSTOSCENE:
		R_AddPolyToScene( args[ 1 ], args[ 2 ], ( polyVert_t* )VMA( 3 ), args[ 4 ] );
		return 0;

	case WMUI_R_ADDLIGHTTOSCENE:
		R_AddLightToScene( ( float* )VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[ 6 ] );
		return 0;

	case WMUI_R_ADDCORONATOSCENE:
		R_AddCoronaToScene( ( float* )VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[ 6 ], args[ 7 ] );
		return 0;

	case WMUI_R_RENDERSCENE:
		CLWM_RenderScene( ( wmrefdef_t* )VMA( 1 ) );
		return 0;

	case WMUI_R_SETCOLOR:
		R_SetColor( ( float* )VMA( 1 ) );
		return 0;

	case WMUI_R_DRAWSTRETCHPIC:
		R_StretchPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[ 9 ] );
		return 0;

	case WMUI_R_MODELBOUNDS:
		R_ModelBounds( args[ 1 ], ( float* )VMA( 2 ), ( float* )VMA( 3 ) );
		return 0;

	case WMUI_UPDATESCREEN:
		SCR_UpdateScreen();
		return 0;

	case WMUI_CM_LERPTAG:
		return CLWM_LerpTag( ( orientation_t* )VMA( 1 ), ( wmrefEntity_t* )VMA( 2 ), ( char* )VMA( 3 ), args[ 4 ] );

	case WMUI_S_REGISTERSOUND:
		return S_RegisterSound( ( char* )VMA( 1 ) );

	case WMUI_S_STARTLOCALSOUND:
		S_StartLocalSound( args[ 1 ], args[ 2 ], 127 );
		return 0;

	case WMUI_KEY_KEYNUMTOSTRINGBUF:
		Key_KeynumToStringBuf( args[ 1 ], ( char* )VMA( 2 ), args[ 3 ] );
		return 0;

	case WMUI_KEY_GETBINDINGBUF:
		Key_GetBindingBuf( args[ 1 ], ( char* )VMA( 2 ), args[ 3 ] );
		return 0;

	case WMUI_KEY_SETBINDING:
		Key_SetBinding( args[ 1 ], ( char* )VMA( 2 ) );
		return 0;

	case WMUI_KEY_ISDOWN:
		return Key_IsDown( args[ 1 ] );

	case WMUI_KEY_GETOVERSTRIKEMODE:
		return Key_GetOverstrikeMode();

	case WMUI_KEY_SETOVERSTRIKEMODE:
		Key_SetOverstrikeMode( args[ 1 ] );
		return 0;

	case WMUI_KEY_CLEARSTATES:
		Key_ClearStates();
		return 0;

	case WMUI_KEY_GETCATCHER:
		return Key_GetCatcher();

	case WMUI_KEY_SETCATCHER:
		KeyWM_SetCatcher( args[ 1 ] );
		return 0;

	case WMUI_GETCLIPBOARDDATA:
		CLT3_GetClipboardData( ( char* )VMA( 1 ), args[ 2 ] );
		return 0;

	case WMUI_GETCLIENTSTATE:
		UIT3_GetClientState( ( uiClientState_t* )VMA( 1 ) );
		return 0;

	case WMUI_GETGLCONFIG:
		CLWM_GetGlconfig( ( wmglconfig_t* )VMA( 1 ) );
		return 0;

	case WMUI_GETCONFIGSTRING:
		return CLWM_GetConfigString( args[ 1 ], ( char* )VMA( 2 ), args[ 3 ] );

	case WMUI_LAN_LOADCACHEDSERVERS:
		LAN_LoadCachedServers();
		return 0;

	case WMUI_LAN_SAVECACHEDSERVERS:
		LAN_SaveServersToCache();
		return 0;

	case WMUI_LAN_ADDSERVER:
		return LAN_AddServer( args[ 1 ], ( char* )VMA( 2 ), ( char* )VMA( 3 ) );

	case WMUI_LAN_REMOVESERVER:
		LAN_RemoveServer( args[ 1 ], ( char* )VMA( 2 ) );
		return 0;

	case WMUI_LAN_GETPINGQUEUECOUNT:
		return CLT3_GetPingQueueCount();

	case WMUI_LAN_CLEARPING:
		CLT3_ClearPing( args[ 1 ] );
		return 0;

	case WMUI_LAN_GETPING:
		CLT3_GetPing( args[ 1 ], ( char* )VMA( 2 ), args[ 3 ], ( int* )VMA( 4 ) );
		return 0;

	case WMUI_LAN_GETPINGINFO:
		CLT3_GetPingInfo( args[ 1 ], ( char* )VMA( 2 ), args[ 3 ] );
		return 0;

	case WMUI_LAN_GETSERVERCOUNT:
		return LAN_GetServerCount( args[ 1 ] );

	case WMUI_LAN_GETSERVERADDRESSSTRING:
		LAN_GetServerAddressString( args[ 1 ], args[ 2 ], ( char* )VMA( 3 ), args[ 4 ] );
		return 0;

	case WMUI_LAN_GETSERVERINFO:
		LAN_GetServerInfo( args[ 1 ], args[ 2 ], ( char* )VMA( 3 ), args[ 4 ] );
		return 0;

	case WMUI_LAN_GETSERVERPING:
		return LAN_GetServerPing( args[ 1 ], args[ 2 ] );

	case WMUI_LAN_MARKSERVERVISIBLE:
		LAN_MarkServerVisible( args[ 1 ], args[ 2 ], args[ 3 ] );
		return 0;

	case WMUI_LAN_SERVERISVISIBLE:
		return LAN_ServerIsVisible( args[ 1 ], args[ 2 ] );

	case WMUI_LAN_UPDATEVISIBLEPINGS:
		return CLT3_UpdateVisiblePings( args[ 1 ] );

	case WMUI_LAN_RESETPINGS:
		LAN_ResetPings( args[ 1 ] );
		return 0;

	case WMUI_LAN_SERVERSTATUS:
		return CLT3_ServerStatus( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] );

	case WMUI_SET_PBCLSTATUS:
		return 0;

	case WMUI_SET_PBSVSTATUS:
		return 0;

	case WMUI_LAN_COMPARESERVERS:
		return LAN_CompareServers( args[ 1 ], args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ] );

	case WMUI_MEMORY_REMAINING:
		return 0x4000000;

	case WMUI_GET_CDKEY:
		CLT3UI_GetCDKey( ( char* )VMA( 1 ), args[ 2 ] );
		return 0;

	case WMUI_SET_CDKEY:
		CLT3UI_SetCDKey( ( char* )VMA( 1 ) );
		return 0;

	case WMUI_R_REGISTERFONT:
		R_RegisterFont( ( char* )VMA( 1 ), args[ 2 ], ( fontInfo_t* )VMA( 3 ) );
		return 0;

	case WMUI_MEMSET:
		return ( qintptr )memset( VMA( 1 ), args[ 2 ], args[ 3 ] );

	case WMUI_MEMCPY:
		return ( qintptr )memcpy( VMA( 1 ), VMA( 2 ), args[ 3 ] );

	case WMUI_STRNCPY:
		String::NCpy( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] );
		return args[ 1 ];

	case WMUI_SIN:
		return FloatAsInt( sin( VMF( 1 ) ) );

	case WMUI_COS:
		return FloatAsInt( cos( VMF( 1 ) ) );

	case WMUI_ATAN2:
		return FloatAsInt( atan2( VMF( 1 ), VMF( 2 ) ) );

	case WMUI_SQRT:
		return FloatAsInt( sqrt( VMF( 1 ) ) );

	case WMUI_FLOOR:
		return FloatAsInt( floor( VMF( 1 ) ) );

	case WMUI_CEIL:
		return FloatAsInt( ceil( VMF( 1 ) ) );

	case WMUI_PC_ADD_GLOBAL_DEFINE:
		return PC_AddGlobalDefine( ( char* )VMA( 1 ) );
	case WMUI_PC_LOAD_SOURCE:
		return PC_LoadSourceHandle( ( char* )VMA( 1 ) );
	case WMUI_PC_FREE_SOURCE:
		return PC_FreeSourceHandle( args[ 1 ] );
	case WMUI_PC_READ_TOKEN:
		return PC_ReadTokenHandleQ3( args[ 1 ], ( q3pc_token_t* )VMA( 2 ) );
	case WMUI_PC_SOURCE_FILE_AND_LINE:
		return PC_SourceFileAndLine( args[ 1 ], ( char* )VMA( 2 ), ( int* )VMA( 3 ) );

	case WMUI_S_STOPBACKGROUNDTRACK:
		S_StopBackgroundTrack();
		return 0;
	case WMUI_S_STARTBACKGROUNDTRACK:
		S_StartBackgroundTrack( ( char* )VMA( 1 ), ( char* )VMA( 2 ), 0 );
		return 0;

	case WMUI_REAL_TIME:
		return Com_RealTime( ( qtime_t* )VMA( 1 ) );

	case WMUI_CIN_PLAYCINEMATIC:
		return CIN_PlayCinematicStretched( ( char* )VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ], args[ 6 ] );

	case WMUI_CIN_STOPCINEMATIC:
		return CIN_StopCinematic( args[ 1 ] );

	case WMUI_CIN_RUNCINEMATIC:
		return CIN_RunCinematic( args[ 1 ] );

	case WMUI_CIN_DRAWCINEMATIC:
		CIN_DrawCinematic( args[ 1 ] );
		return 0;

	case WMUI_CIN_SETEXTENTS:
		CIN_SetExtents( args[ 1 ], args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ] );
		return 0;

	case WMUI_R_REMAP_SHADER:
		R_RemapShader( ( char* )VMA( 1 ), ( char* )VMA( 2 ), ( char* )VMA( 3 ) );
		return 0;

	case WMUI_VERIFY_CDKEY:
		return CLT3_CDKeyValidate( ( char* )VMA( 1 ), ( char* )VMA( 2 ) );

	case WMUI_CL_GETLIMBOSTRING:
		return CLT3_GetLimboString( args[ 1 ], ( char* )VMA( 2 ) );

	case WMUI_CL_TRANSLATE_STRING:
		CL_TranslateString( ( char* )VMA( 1 ), ( char* )VMA( 2 ) );
		return 0;

	case WMUI_CHECKAUTOUPDATE:
		return 0;

	case WMUI_GET_AUTOUPDATE:
		return 0;

	case WMUI_OPENURL:
		CLT3_OpenURL( ( const char* )VMA( 1 ) );
		return 0;

	default:
		common->Error( "Bad UI system trap: %i", static_cast<int>( args[ 0 ] ) );
	}
	return 0;
}
Ejemplo n.º 8
0
/*
* Mod_LoadSkeletalModel
*/
void Mod_LoadSkeletalModel( model_t *mod, const model_t *parent, void *buffer, bspFormatDesc_t *unused )
{
	unsigned int i, j, k;
	size_t filesize;
	qbyte *pbase;
	size_t memsize;
	qbyte *pmem;
	iqmheader_t *header;
	char *texts;
	iqmvertexarray_t *va;
	iqmjoint_t *joints;
	bonepose_t *baseposes;
	iqmpose_t *poses;
	unsigned short *framedata;
	const int *inelems;
	elem_t *outelems;
	iqmmesh_t *inmesh;
	iqmbounds_t *inbounds;
	float *vposition, *vtexcoord, *vnormal, *vtangent;
	qbyte *vblendindices_byte, *vblendweights_byte;
	int *vblendindexes_int;
	float *vblendweights_float;
	mskmodel_t *poutmodel;

	baseposes = NULL;
	header = ( iqmheader_t * )buffer;

	// check IQM magic
	if( memcmp( header->magic, "INTERQUAKEMODEL", 16 ) ) {
		ri.Com_Printf( S_COLOR_RED "ERROR: %s is not an Inter-Quake Model\n", mod->name );
		goto error;
	}

	// check header version
	header->version = LittleLong( header->version );
	if( header->version != IQM_VERSION ) {
		ri.Com_Printf( S_COLOR_RED "ERROR: %s has wrong type number (%i should be %i)\n", mod->name, header->version, IQM_VERSION );
		goto error;
	}

	// byteswap header
#define H_SWAP(s) (header->s = LittleLong( header->s ))
	H_SWAP( filesize );
	H_SWAP( flags );
	H_SWAP( num_text );
	H_SWAP( ofs_text );
	H_SWAP( num_meshes );
	H_SWAP( ofs_meshes );
	H_SWAP( num_vertexarrays );
	H_SWAP( num_vertexes );
	H_SWAP( ofs_vertexarrays );
	H_SWAP( num_triangles );
	H_SWAP( ofs_triangles );
	H_SWAP( ofs_adjacency );
	H_SWAP( num_joints );
	H_SWAP( ofs_joints );
	H_SWAP( num_poses );
	H_SWAP( ofs_poses );
	H_SWAP( num_anims );
	H_SWAP( ofs_anims );
	H_SWAP( num_frames );
	H_SWAP( num_framechannels );
	H_SWAP( ofs_frames );
	H_SWAP( ofs_bounds );
	H_SWAP( num_comment );
	H_SWAP( ofs_comment );
	H_SWAP( num_extensions );
	H_SWAP( ofs_extensions );
#undef H_SWAP

	if( header->num_triangles < 1 || header->num_vertexes < 3 || header->num_vertexarrays < 1 || header->num_meshes < 1 ) {
		ri.Com_Printf( S_COLOR_RED "ERROR: %s has no geometry\n", mod->name );
		goto error;
	}
	if( header->num_frames < 1 || header->num_anims < 1 ) {
		ri.Com_Printf( S_COLOR_RED "ERROR: %s has no animations\n", mod->name );
		goto error;
	}
	if( header->num_joints != header->num_poses ) {
		ri.Com_Printf( S_COLOR_RED "ERROR: %s has an invalid number of poses: %i vs %i\n", mod->name, header->num_joints, header->num_poses );
		goto error;
	}
	if( !header->ofs_bounds ) {
		ri.Com_Printf( S_COLOR_RED "ERROR: %s has no frame bounds\n", mod->name );
		goto error;
	}

	pbase = ( qbyte * )buffer;
	filesize = header->filesize;

	// check data offsets against the filesize
	if( header->ofs_text + header->num_text > filesize
		|| header->ofs_vertexarrays + header->num_vertexarrays * sizeof( iqmvertexarray_t ) > filesize
		|| header->ofs_joints + header->num_joints * sizeof( iqmjoint_t ) > filesize
		|| header->ofs_frames + header->num_frames * header->num_framechannels * sizeof( unsigned short ) > filesize
		|| header->ofs_triangles + header->num_triangles * sizeof( int[3] ) > filesize
		|| header->ofs_meshes + header->num_meshes * sizeof( iqmmesh_t ) > filesize
		|| header->ofs_bounds + header->num_frames * sizeof( iqmbounds_t ) > filesize
		) {
		ri.Com_Printf( S_COLOR_RED "ERROR: %s has invalid size or offset information\n", mod->name );
		goto error;
	}

	poutmodel = mod->extradata = Mod_Malloc( mod, sizeof( *poutmodel ) );


	// load text
	texts = Mod_Malloc( mod, header->num_text + 1 );
	if( header->ofs_text ) {
		memcpy( texts, (const char *)(pbase + header->ofs_text), header->num_text );
	}
	texts[header->ofs_text] = '\0';


	// load vertex arrays
	vposition = NULL;
	vtexcoord = NULL;
	vnormal = NULL;
	vtangent = NULL;
	vblendindices_byte = NULL;
	vblendindexes_int = NULL;
	vblendweights_byte = NULL;
	vblendweights_float = NULL;

	va = ( iqmvertexarray_t * )( pbase + header->ofs_vertexarrays );
	for( i = 0; i < header->num_vertexarrays; i++ ) {
		size_t vsize;

		va[i].type = LittleLong( va[i].type );
		va[i].flags = LittleLong( va[i].flags );
		va[i].format = LittleLong( va[i].format );
		va[i].size = LittleLong( va[i].size );
		va[i].offset = LittleLong( va[i].offset );

		vsize = header->num_vertexes*va[i].size;
		switch( va[i].format ) { 
			case IQM_FLOAT:
				vsize *= sizeof( float );
				break;
			case IQM_INT:
			case IQM_UINT:
				vsize *= sizeof( int );
				break;
			case IQM_BYTE:
			case IQM_UBYTE:
				vsize *= sizeof( unsigned char );
				break;
			default:
				continue;
		}

		if( va[i].offset + vsize > filesize ) {
			continue;
		}

		switch( va[i].type ) {
			case IQM_POSITION:
				if( va[i].format == IQM_FLOAT && va[i].size == 3 ) {
					vposition = ( float * )( pbase + va[i].offset );
				}
				break;
			case IQM_TEXCOORD:
				if( va[i].format == IQM_FLOAT && va[i].size == 2 ) {
					vtexcoord = ( float * )( pbase + va[i].offset );
				}
				break;
			case IQM_NORMAL:
				if( va[i].format == IQM_FLOAT && va[i].size == 3 ) {
					vnormal = ( float * )( pbase + va[i].offset );
				}
				break;
			case IQM_TANGENT:
				if( va[i].format == IQM_FLOAT && va[i].size == 4 ) {
					vtangent = ( float * )( pbase + va[i].offset );
				}
				break;
			case IQM_BLENDINDEXES:
				if( va[i].size != SKM_MAX_WEIGHTS )
					break;
				if( va[i].format == IQM_BYTE || va[i].format == IQM_UBYTE ) {
					vblendindices_byte = ( qbyte * )( pbase + va[i].offset );
				}
				else if( va[i].format == IQM_INT || va[i].format == IQM_UINT ) {
					vblendindexes_int = ( int * )( pbase + va[i].offset );
				}
				break;
			case IQM_BLENDWEIGHTS:
				if( va[i].size != SKM_MAX_WEIGHTS )
					break;
				if( va[i].format == IQM_UBYTE ) {
					vblendweights_byte = ( qbyte * )( pbase + va[i].offset );
				}
				else if( va[i].format == IQM_FLOAT ) {
					vblendweights_float = ( float * )( pbase + va[i].offset );
				}
				break;
			default:
				break;
		}
	}

	if( !vposition || !vtexcoord 
		|| !(vblendindices_byte || vblendindexes_int) 
		|| !(vblendweights_byte || vblendweights_float) ) {
		ri.Com_Printf( S_COLOR_RED "ERROR: %s is missing vertex array data\n", mod->name );
		goto error;
	}

	// load joints
	memsize = 0;
	memsize += sizeof( bonepose_t ) * header->num_joints;
	pmem = Mod_Malloc( mod, memsize );

	baseposes = ( void * )pmem; pmem += sizeof( *baseposes );

	memsize = 0;
	memsize += sizeof( mskbone_t ) * header->num_joints;
	memsize += sizeof( bonepose_t ) * header->num_joints;
	pmem = Mod_Malloc( mod, memsize );

	poutmodel->numbones = header->num_joints;
	poutmodel->bones = ( void * )pmem; pmem += sizeof( *poutmodel->bones ) * poutmodel->numbones;
	poutmodel->invbaseposes = ( void * )pmem; pmem += sizeof( *poutmodel->invbaseposes ) * poutmodel->numbones;

	joints = ( iqmjoint_t * )( pbase + header->ofs_joints );
	for( i = 0; i < poutmodel->numbones; i++ ) {
		joints[i].name = LittleLong( joints[i].name );
		joints[i].parent = LittleLong( joints[i].parent );

		for( j = 0; j < 3; j++ ) {
			joints[i].translate[j] = LittleFloat( joints[i].translate[j] );
			joints[i].rotate[j] = LittleFloat( joints[i].rotate[j] );
			joints[i].scale[j] = LittleFloat( joints[i].scale[j] );
		}

		if( joints[i].parent >= (int)i ) {
			ri.Com_Printf( S_COLOR_RED "ERROR: %s bone[%i].parent(%i) >= %i\n", mod->name, i, joints[i].parent, i );
			goto error;
		}

		poutmodel->bones[i].name = texts + joints[i].name;
		poutmodel->bones[i].parent = joints[i].parent;

		DualQuat_FromQuat3AndVector( joints[i].rotate, joints[i].translate, baseposes[i].dualquat );

		// scale is unused

		// reconstruct invserse bone pose

		if( joints[i].parent >= 0 )
		{
			bonepose_t bp, *pbp;
			bp = baseposes[i];
			pbp = &baseposes[joints[i].parent];

			DualQuat_Multiply( pbp->dualquat, bp.dualquat, baseposes[i].dualquat );
		}

		DualQuat_Copy( baseposes[i].dualquat, poutmodel->invbaseposes[i].dualquat );
		DualQuat_Invert( poutmodel->invbaseposes[i].dualquat );
	}


	// load frames
	poses = ( iqmpose_t * )( pbase + header->ofs_poses );
	for( i = 0; i < header->num_poses; i++ ) {
		poses[i].parent = LittleLong( poses[i].parent );
		poses[i].mask = LittleLong( poses[i].mask );

		for( j = 0; j < 10; j++ ) {
			poses[i].channeloffset[j] = LittleFloat( poses[i].channeloffset[j] );
			poses[i].channelscale[j] = LittleFloat( poses[i].channelscale[j] );
		}
	}

	memsize = 0;
	memsize += sizeof( mskframe_t ) * header->num_frames;
	memsize += sizeof( bonepose_t ) * header->num_joints * header->num_frames;
	pmem = Mod_Malloc( mod, memsize );

	poutmodel->numframes = header->num_frames;
	poutmodel->frames = ( mskframe_t * )pmem; pmem += sizeof( mskframe_t ) * poutmodel->numframes;

	framedata = ( unsigned short * )( pbase + header->ofs_frames );
	for( i = 0; i < header->num_frames; i++ ) {
		bonepose_t *pbp;
		vec3_t translate;
		quat_t rotate;

		poutmodel->frames[i].boneposes = ( bonepose_t * )pmem; pmem += sizeof( bonepose_t ) * poutmodel->numbones;

		for( j = 0, pbp = poutmodel->frames[i].boneposes; j < header->num_poses; j++, pbp++ ) {
			translate[0] = poses[j].channeloffset[0]; if( poses[j].mask & 0x01 ) translate[0] += *framedata++ * poses[j].channelscale[0];
			translate[1] = poses[j].channeloffset[1]; if( poses[j].mask & 0x02 ) translate[1] += *framedata++ * poses[j].channelscale[1];
			translate[2] = poses[j].channeloffset[2]; if( poses[j].mask & 0x04 ) translate[2] += *framedata++ * poses[j].channelscale[2];

			rotate[0] = poses[j].channeloffset[3]; if( poses[j].mask & 0x08 ) rotate[0] += *framedata++ * poses[j].channelscale[3];
			rotate[1] = poses[j].channeloffset[4]; if( poses[j].mask & 0x10 ) rotate[1] += *framedata++ * poses[j].channelscale[4];
			rotate[2] = poses[j].channeloffset[5]; if( poses[j].mask & 0x20 ) rotate[2] += *framedata++ * poses[j].channelscale[5];
			rotate[3] = poses[j].channeloffset[6]; if( poses[j].mask & 0x40 ) rotate[3] += *framedata++ * poses[j].channelscale[6];
			if( rotate[3] > 0 ) {
				Vector4Inverse( rotate );
			}
			Vector4Normalize( rotate );

			// scale is unused
			if( poses[j].mask & 0x80  ) framedata++;
			if( poses[j].mask & 0x100 ) framedata++;
			if( poses[j].mask & 0x200 ) framedata++;

			DualQuat_FromQuatAndVector( rotate, translate, pbp->dualquat );
		}
	}


	// load triangles
	memsize = 0;
	memsize += sizeof( *outelems ) * header->num_triangles * 3;
	pmem = Mod_Malloc( mod, memsize );

	poutmodel->numtris = header->num_triangles;
	poutmodel->elems = ( elem_t * )pmem; pmem += sizeof( *outelems ) * header->num_triangles * 3;

	inelems = ( const int * )(pbase + header->ofs_triangles);
	outelems = poutmodel->elems;

	for( i = 0; i < header->num_triangles; i++ ) {
		for( j = 0; j < 3; j++ ) {
			outelems[j] = LittleLong( inelems[j] );
		}
		inelems += 3;
		outelems += 3;
	}


	// load vertices
	memsize = 0;
	memsize += sizeof( *poutmodel->sVectorsArray ) * header->num_vertexes;	// 16-bytes aligned
	memsize += sizeof( *poutmodel->xyzArray ) * header->num_vertexes;
	memsize += sizeof( *poutmodel->normalsArray ) * header->num_vertexes;
	memsize += sizeof( *poutmodel->stArray ) * header->num_vertexes;
	memsize += sizeof( *poutmodel->blendWeights ) * header->num_vertexes * SKM_MAX_WEIGHTS;
	memsize += sizeof( *poutmodel->blendIndices ) * header->num_vertexes * SKM_MAX_WEIGHTS;
	pmem = Mod_Malloc( mod, memsize );

	poutmodel->numverts = header->num_vertexes;

	// S-vectors
	poutmodel->sVectorsArray = ( vec4_t * )pmem; pmem += sizeof( *poutmodel->sVectorsArray ) * header->num_vertexes;

	if( vtangent ) {
		for( i = 0; i < header->num_vertexes; i++ ) {
			for( j = 0; j < 4; j++ ) {
				poutmodel->sVectorsArray[i][j] = LittleFloat( vtangent[j] );
			}
			vtangent += 4;
		}
	}

	// XYZ positions
	poutmodel->xyzArray = ( vec4_t * )pmem; pmem += sizeof( *poutmodel->xyzArray ) * header->num_vertexes;
	for( i = 0; i < header->num_vertexes; i++ ) {
		for( j = 0; j < 3; j++ ) {
			poutmodel->xyzArray[i][j] = LittleFloat( vposition[j] );
		}
		poutmodel->xyzArray[i][3] = 1;
		vposition += 3;
	}

	// normals
	poutmodel->normalsArray = ( vec4_t * )pmem; pmem += sizeof( *poutmodel->normalsArray ) * header->num_vertexes;
	for( i = 0; i < header->num_vertexes; i++ ) {
		for( j = 0; j < 3; j++ ) {
			poutmodel->normalsArray[i][j] = LittleFloat( vnormal[j] );
		}
		poutmodel->normalsArray[i][3] = 0;
		vnormal += 3;
	}

	// texture coordinates
	poutmodel->stArray = ( vec2_t * )pmem; pmem += sizeof( *poutmodel->stArray ) * header->num_vertexes;
	for( i = 0; i < header->num_vertexes; i++ ) {
		for( j = 0; j < 2; j++ ) {
			poutmodel->stArray[i][j] = LittleFloat( vtexcoord[j] );
		}
		vtexcoord += 2;
	}

	if( !vtangent ) {
		// if the loaded file is missing precomputed S-vectors, compute them now
		R_BuildTangentVectors( poutmodel->numverts, poutmodel->xyzArray, poutmodel->normalsArray, poutmodel->stArray, 
			poutmodel->numtris, poutmodel->elems, poutmodel->sVectorsArray );
	}

	// blend indices
	poutmodel->blendIndices = ( qbyte * )pmem; pmem += sizeof( *poutmodel->blendIndices ) * header->num_vertexes * SKM_MAX_WEIGHTS;
	if( vblendindices_byte ) {
		memcpy( poutmodel->blendIndices, vblendindices_byte, sizeof( qbyte ) * header->num_vertexes * SKM_MAX_WEIGHTS );
	} else if( vblendindexes_int ) {
		for( j = 0; j < header->num_vertexes * SKM_MAX_WEIGHTS; j++ ) {
			poutmodel->blendIndices[j] = LittleLong( vblendindexes_int[j] );
		}
	}

	// blend weights
	poutmodel->blendWeights = ( qbyte * )pmem; pmem += sizeof( *poutmodel->blendWeights ) * header->num_vertexes * SKM_MAX_WEIGHTS;
	if( vblendweights_byte ) {
		memcpy( poutmodel->blendWeights, vblendweights_byte, sizeof( qbyte ) * header->num_vertexes * SKM_MAX_WEIGHTS );
	}
	else if( vblendweights_float ) {
		for( j = 0; j < header->num_vertexes * SKM_MAX_WEIGHTS; j++ ) {
			poutmodel->blendWeights[j] = LittleFloat( vblendweights_float[j] ) * 255.0f;
		}
	}


	// blends
	memsize = 0;
	memsize += poutmodel->numverts * ( sizeof( mskblend_t ) + sizeof( unsigned int ) );
	pmem = Mod_Malloc( mod, memsize );

	poutmodel->numblends = 0;
	poutmodel->blends = ( mskblend_t * )pmem; pmem += sizeof( *poutmodel->blends ) * poutmodel->numverts;
	poutmodel->vertexBlends = ( unsigned int * )pmem;

	vblendindices_byte = poutmodel->blendIndices;
	vblendweights_byte = poutmodel->blendWeights;

	for( i = 0; i < poutmodel->numverts; i++ ) {
		mskblend_t blend;

		for( j = 0; j < SKM_MAX_WEIGHTS; j++ ) {
			blend.indices[j] = vblendindices_byte[j];
			blend.weights[j] = vblendweights_byte[j];
		}

		poutmodel->vertexBlends[i] = Mod_SkeletalModel_AddBlend( poutmodel, &blend );

		vblendindices_byte += SKM_MAX_WEIGHTS;
		vblendweights_byte += SKM_MAX_WEIGHTS;
	}

	// meshes
	memsize = 0;
	memsize += sizeof( mskmesh_t ) * header->num_meshes;
	memsize += sizeof( drawSurfaceSkeletal_t ) * header->num_meshes;
	pmem = Mod_Malloc( mod, memsize );

	poutmodel->nummeshes = header->num_meshes;
	poutmodel->meshes = ( mskmesh_t * )pmem; pmem += sizeof( *poutmodel->meshes ) * header->num_meshes;

	inmesh = ( iqmmesh_t * )(pbase + header->ofs_meshes);
	for( i = 0; i < header->num_meshes; i++ ) {
		inmesh[i].name = LittleLong( inmesh[i].name );
		inmesh[i].material = LittleLong( inmesh[i].material );
		inmesh[i].first_vertex = LittleLong( inmesh[i].first_vertex );
		inmesh[i].num_vertexes = LittleLong( inmesh[i].num_vertexes );
		inmesh[i].first_triangle = LittleLong( inmesh[i].first_triangle );
		inmesh[i].num_triangles = LittleLong( inmesh[i].num_triangles );

		poutmodel->meshes[i].name = texts + inmesh[i].name;
		Mod_StripLODSuffix( poutmodel->meshes[i].name );

		poutmodel->meshes[i].skin.name = texts + inmesh[i].material;
		poutmodel->meshes[i].skin.shader = R_RegisterSkin( poutmodel->meshes[i].skin.name );

		poutmodel->meshes[i].elems = poutmodel->elems + inmesh[i].first_triangle * 3;
		poutmodel->meshes[i].numtris = inmesh[i].num_triangles;

		poutmodel->meshes[i].numverts = inmesh[i].num_vertexes;
		poutmodel->meshes[i].xyzArray = poutmodel->xyzArray + inmesh[i].first_vertex;
		poutmodel->meshes[i].normalsArray = poutmodel->normalsArray + inmesh[i].first_vertex;
		poutmodel->meshes[i].stArray = poutmodel->stArray + inmesh[i].first_vertex;
		poutmodel->meshes[i].sVectorsArray = poutmodel->sVectorsArray + inmesh[i].first_vertex;

		poutmodel->meshes[i].blendIndices = poutmodel->blendIndices + inmesh[i].first_vertex * SKM_MAX_WEIGHTS;
		poutmodel->meshes[i].blendWeights = poutmodel->blendWeights + inmesh[i].first_vertex * SKM_MAX_WEIGHTS;

		poutmodel->meshes[i].vertexBlends = poutmodel->vertexBlends + inmesh[i].first_vertex;

		// elements are always offset to start vertex 0 for each mesh
		outelems = poutmodel->meshes[i].elems;
		for( j = 0; j < poutmodel->meshes[i].numtris; j++ ) {
			outelems[0] -= inmesh[i].first_vertex;
			outelems[1] -= inmesh[i].first_vertex;
			outelems[2] -= inmesh[i].first_vertex;
			outelems += 3;
		}

		poutmodel->meshes[i].maxWeights = 1;

		vblendweights_byte = poutmodel->meshes[i].blendWeights;
		for( j = 0; j < poutmodel->meshes[i].numverts; j++ ) {
			for( k = 1; k < SKM_MAX_WEIGHTS && vblendweights_byte[k]; k++ );

			if( k > poutmodel->meshes[i].maxWeights ) {
				poutmodel->meshes[i].maxWeights = k;
				if( k == SKM_MAX_WEIGHTS ) {
					break;
				}
			}
			vblendweights_byte += SKM_MAX_WEIGHTS;
		}

		// creating a VBO only makes sense if GLSL is present and the number of bones 
		// we can handle on the GPU is sufficient
		if( glConfig.ext.vertex_buffer_object && poutmodel->numbones <= glConfig.maxGLSLBones ) {
			// build a static vertex buffer object for this mesh
			Mod_SkeletalBuildStaticVBOForMesh( &poutmodel->meshes[i] );
		}
	}

	poutmodel->drawSurfs = ( drawSurfaceSkeletal_t * )pmem; pmem += sizeof( *poutmodel->drawSurfs ) * header->num_meshes;
	for( i = 0; i < header->num_meshes; i++ ) {
		poutmodel->drawSurfs[i].type = ST_SKELETAL;
		poutmodel->drawSurfs[i].model = mod;
		poutmodel->drawSurfs[i].mesh = poutmodel->meshes + i;
	}

	// bounds
	ClearBounds( mod->mins, mod->maxs );

	inbounds = ( iqmbounds_t * )(pbase + header->ofs_bounds);
	for( i = 0; i < header->num_frames; i++ ) {
		for( j = 0; j < 3; j++ ) {
			inbounds[i].bbmin[j] = LittleFloat( inbounds[i].bbmin[j] );
			inbounds[i].bbmax[j] = LittleFloat( inbounds[i].bbmax[j] );
		}
		inbounds[i].radius = LittleFloat( inbounds[i].radius );
		inbounds[i].xyradius = LittleFloat( inbounds[i].xyradius );

		VectorCopy( inbounds[i].bbmin, poutmodel->frames[i].mins );
		VectorCopy( inbounds[i].bbmax, poutmodel->frames[i].maxs );
		poutmodel->frames[i].radius = inbounds[i].radius;

		AddPointToBounds( poutmodel->frames[i].mins, mod->mins, mod->maxs );
		AddPointToBounds( poutmodel->frames[i].maxs, mod->mins, mod->maxs );
	}

	mod->radius = RadiusFromBounds( mod->mins, mod->maxs );
	mod->type = mod_skeletal;
	mod->registrationSequence = rsh.registrationSequence;
	mod->touch = &Mod_TouchSkeletalModel;

	R_Free( baseposes );
	return;

error:
	if( baseposes ) {
		R_Free( baseposes );
	}
	mod->type = mod_bad;
}
Ejemplo n.º 9
0
/*
* Mod_LoadAliasMD3Model
*/
void Mod_LoadAliasMD3Model( model_t *mod, model_t *parent, void *buffer, bspFormatDesc_t *unused )
{
	int version, i, j, l;
	int bufsize, numverts;
	qbyte *buf;
	dmd3header_t *pinmodel;
	dmd3frame_t *pinframe;
	dmd3tag_t *pintag;
	dmd3mesh_t *pinmesh;
	dmd3skin_t *pinskin;
	dmd3coord_t *pincoord;
	dmd3vertex_t *pinvert;
	elem_t *pinelem, *poutelem;
	maliasvertex_t *poutvert;
	vec2_t *poutcoord;
	maliasskin_t *poutskin;
	maliasmesh_t *poutmesh;
	maliastag_t *pouttag;
	maliasframe_t *poutframe;
	maliasmodel_t *poutmodel;
	drawSurfaceAlias_t *drawSurf;

	pinmodel = ( dmd3header_t * )buffer;
	version = LittleLong( pinmodel->version );

	if( version != MD3_ALIAS_VERSION )
		ri.Com_Error( ERR_DROP, "%s has wrong version number (%i should be %i)",
		mod->name, version, MD3_ALIAS_VERSION );

	mod->type = mod_alias;
	mod->extradata = poutmodel = Mod_Malloc( mod, sizeof( maliasmodel_t ) );
	mod->radius = 0;
	mod->registrationSequence = rf.registrationSequence;
	mod->touch = &Mod_TouchAliasModel;

	ClearBounds( mod->mins, mod->maxs );

	// byte swap the header fields and sanity check
	poutmodel->numframes = LittleLong( pinmodel->num_frames );
	poutmodel->numtags = LittleLong( pinmodel->num_tags );
	poutmodel->nummeshes = LittleLong( pinmodel->num_meshes );
	poutmodel->numskins = 0;

	if( poutmodel->numframes <= 0 )
		ri.Com_Error( ERR_DROP, "model %s has no frames", mod->name );
	//	else if( poutmodel->numframes > MD3_MAX_FRAMES )
	//		ri.Com_Error( ERR_DROP, "model %s has too many frames", mod->name );

	if( poutmodel->numtags > MD3_MAX_TAGS )
		ri.Com_Error( ERR_DROP, "model %s has too many tags", mod->name );
	else if( poutmodel->numtags < 0 )
		ri.Com_Error( ERR_DROP, "model %s has invalid number of tags", mod->name );

	if( poutmodel->nummeshes < 0 )
		ri.Com_Error( ERR_DROP, "model %s has invalid number of meshes", mod->name );
	else if( !poutmodel->nummeshes && !poutmodel->numtags )
		ri.Com_Error( ERR_DROP, "model %s has no meshes and no tags", mod->name );
	//	else if( poutmodel->nummeshes > MD3_MAX_MESHES )
	//		ri.Com_Error( ERR_DROP, "model %s has too many meshes", mod->name );

	bufsize = poutmodel->numframes * ( sizeof( maliasframe_t ) + sizeof( maliastag_t ) * poutmodel->numtags ) +
		poutmodel->nummeshes * sizeof( maliasmesh_t ) + 
		poutmodel->nummeshes * sizeof( drawSurfaceAlias_t );
	buf = Mod_Malloc( mod, bufsize );

	//
	// load the frames
	//
	pinframe = ( dmd3frame_t * )( ( qbyte * )pinmodel + LittleLong( pinmodel->ofs_frames ) );
	poutframe = poutmodel->frames = ( maliasframe_t * )buf; buf += sizeof( maliasframe_t ) * poutmodel->numframes;
	for( i = 0; i < poutmodel->numframes; i++, pinframe++, poutframe++ )
	{
		for( j = 0; j < 3; j++ )
		{
			poutframe->scale[j] = MD3_XYZ_SCALE;
			poutframe->translate[j] = LittleFloat( pinframe->translate[j] );
		}

		// never trust the modeler utility and recalculate bbox and radius
		ClearBounds( poutframe->mins, poutframe->maxs );
	}

	//
	// load the tags
	//
	pintag = ( dmd3tag_t * )( ( qbyte * )pinmodel + LittleLong( pinmodel->ofs_tags ) );
	pouttag = poutmodel->tags = ( maliastag_t * )buf; buf += sizeof( maliastag_t ) * poutmodel->numframes * poutmodel->numtags;
	for( i = 0; i < poutmodel->numframes; i++ )
	{
		for( l = 0; l < poutmodel->numtags; l++, pintag++, pouttag++ )
		{
			mat3_t axis;

			for( j = 0; j < 3; j++ )
			{
				axis[AXIS_FORWARD+j] = LittleFloat( pintag->axis[0][j] );
				axis[AXIS_RIGHT+j] = LittleFloat( pintag->axis[1][j] );
				axis[AXIS_UP+j] = LittleFloat( pintag->axis[2][j] );
				pouttag->origin[j] = LittleFloat( pintag->origin[j] );
			}

			Quat_FromMatrix3( axis, pouttag->quat );
			Quat_Normalize( pouttag->quat );

			Q_strncpyz( pouttag->name, pintag->name, MD3_MAX_PATH );
		}
	}

	//
	// allocate drawSurfs
	//
	drawSurf = poutmodel->drawSurfs = ( drawSurfaceAlias_t * )buf; buf += sizeof( drawSurfaceAlias_t ) * poutmodel->nummeshes;
	for( i = 0; i < poutmodel->nummeshes; i++, drawSurf++ )
	{
		drawSurf->type = ST_ALIAS;
		drawSurf->model = mod;
		drawSurf->mesh = poutmodel->meshes + i;
	}

	//
	// load meshes
	//
	pinmesh = ( dmd3mesh_t * )( ( qbyte * )pinmodel + LittleLong( pinmodel->ofs_meshes ) );
	poutmesh = poutmodel->meshes = ( maliasmesh_t * )buf; buf += sizeof( maliasmesh_t ) * poutmodel->nummeshes;
	for( i = 0; i < poutmodel->nummeshes; i++, poutmesh++ )
	{
		if( strncmp( (const char *)pinmesh->id, IDMD3HEADER, 4 ) )
			ri.Com_Error( ERR_DROP, "mesh %s in model %s has wrong id (%s should be %s)",
			pinmesh->name, mod->name, pinmesh->id, IDMD3HEADER );

		Q_strncpyz( poutmesh->name, pinmesh->name, MD3_MAX_PATH );

		Mod_StripLODSuffix( poutmesh->name );

		poutmesh->numtris = LittleLong( pinmesh->num_tris );
		poutmesh->numskins = LittleLong( pinmesh->num_skins );
		poutmesh->numverts = numverts = LittleLong( pinmesh->num_verts );

		/*		if( poutmesh->numskins <= 0 )
		ri.Com_Error( ERR_DROP, "mesh %i in model %s has no skins", i, mod->name );
		else*/ if( poutmesh->numskins > MD3_MAX_SHADERS )
			ri.Com_Error( ERR_DROP, "mesh %i in model %s has too many skins", i, mod->name );
		if( poutmesh->numtris <= 0 )
			ri.Com_Error( ERR_DROP, "mesh %i in model %s has no elements", i, mod->name );
		else if( poutmesh->numtris > MD3_MAX_TRIANGLES )
			ri.Com_Error( ERR_DROP, "mesh %i in model %s has too many triangles", i, mod->name );
		if( poutmesh->numverts <= 0 )
			ri.Com_Error( ERR_DROP, "mesh %i in model %s has no vertices", i, mod->name );
		else if( poutmesh->numverts > MD3_MAX_VERTS )
			ri.Com_Error( ERR_DROP, "mesh %i in model %s has too many vertices", i, mod->name );

		bufsize = sizeof( maliasskin_t ) * poutmesh->numskins + poutmesh->numtris * sizeof( elem_t ) * 3 +
			numverts * ( sizeof( vec2_t ) + sizeof( maliasvertex_t ) * poutmodel->numframes );
		buf = Mod_Malloc( mod, bufsize );

		//
		// load the skins
		//
		pinskin = ( dmd3skin_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->ofs_skins ) );
		poutskin = poutmesh->skins = ( maliasskin_t * )buf; buf += sizeof( maliasskin_t ) * poutmesh->numskins;
		for( j = 0; j < poutmesh->numskins; j++, pinskin++, poutskin++ ) {
			Q_strncpyz( poutskin->name, pinskin->name, sizeof( poutskin->name ) );
			poutskin->shader = R_RegisterSkin( poutskin->name );
		}
		
		//
		// load the elems
		//
		pinelem = ( elem_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->ofs_elems ) );
		poutelem = poutmesh->elems = ( elem_t * )buf; buf += poutmesh->numtris * sizeof( elem_t ) * 3;
		for( j = 0; j < poutmesh->numtris; j++, pinelem += 3, poutelem += 3 )
		{
			poutelem[0] = (elem_t)LittleLong( pinelem[0] );
			poutelem[1] = (elem_t)LittleLong( pinelem[1] );
			poutelem[2] = (elem_t)LittleLong( pinelem[2] );
		}

		//
		// load the texture coordinates
		//
		pincoord = ( dmd3coord_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->ofs_tcs ) );
		poutcoord = poutmesh->stArray = ( vec2_t * )buf; buf += poutmesh->numverts * sizeof( vec2_t );
		for( j = 0; j < poutmesh->numverts; j++, pincoord++ )
		{
			poutcoord[j][0] = LittleFloat( pincoord->st[0] );
			poutcoord[j][1] = LittleFloat( pincoord->st[1] );
		}

		//
		// load the vertexes and normals
		//
		pinvert = ( dmd3vertex_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->ofs_verts ) );
		poutvert = poutmesh->vertexes = ( maliasvertex_t * )buf;
		for( l = 0, poutframe = poutmodel->frames; l < poutmodel->numframes; l++, poutframe++, pinvert += poutmesh->numverts, poutvert += poutmesh->numverts )
		{
			vec3_t v;

			for( j = 0; j < poutmesh->numverts; j++ )
			{
				poutvert[j].point[0] = LittleShort( pinvert[j].point[0] );
				poutvert[j].point[1] = LittleShort( pinvert[j].point[1] );
				poutvert[j].point[2] = LittleShort( pinvert[j].point[2] );

				poutvert[j].latlong[0] = pinvert[j].norm[0];
				poutvert[j].latlong[1] = pinvert[j].norm[1];

				VectorCopy( poutvert[j].point, v );
				AddPointToBounds( v, poutframe->mins, poutframe->maxs );
			}
		}

		pinmesh = ( dmd3mesh_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->meshsize ) );
	}

	//
	// setup drawSurfs
	//
	for( i = 0; i < poutmodel->nummeshes; i++ )
	{
		drawSurf = poutmodel->drawSurfs + i;
		drawSurf->type = ST_ALIAS;
		drawSurf->model = mod;
		drawSurf->mesh = poutmodel->meshes + i;
	}

	//
	// build S and T vectors for frame 0
	//
	Mod_AliasBuildMeshesForFrame0( mod );

	//
	// calculate model bounds
	//
	poutframe = poutmodel->frames;
	for( i = 0; i < poutmodel->numframes; i++, poutframe++ )
	{
		VectorMA( poutframe->translate, MD3_XYZ_SCALE, poutframe->mins, poutframe->mins );
		VectorMA( poutframe->translate, MD3_XYZ_SCALE, poutframe->maxs, poutframe->maxs );
		poutframe->radius = RadiusFromBounds( poutframe->mins, poutframe->maxs );

		AddPointToBounds( poutframe->mins, mod->mins, mod->maxs );
		AddPointToBounds( poutframe->maxs, mod->mins, mod->maxs );
		mod->radius = max( mod->radius, poutframe->radius );
	}
}
Ejemplo n.º 10
0
qboolean PlayerConfig_MenuInit (void)
{
	extern cvar_t *name;
	extern cvar_t *team;
	extern cvar_t *skin;
	char currentdirectory[1024];
	char currentskin[1024];
	char scratch[MAX_QPATH];
	int i = 0;
	int y = 0;

	int currentdirectoryindex = 0;
	int currentskinindex = 0;

	cvar_t *hand = Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );

	static const char *handedness[] = { "right", "left", "center", 0 };

	PlayerConfig_ScanDirectories ();

	if (s_numplayermodels == 0)
		return false;

	if ( hand->value < 0 || hand->value > 2 )
		Cvar_SetValue( "hand", 0 );

//	strncpy( currentdirectory, skin->string );
	Q_strncpyz( currentdirectory, skin->string, sizeof(currentdirectory) );

	if ( strchr( currentdirectory, '/' ) )
	{
	//	strncpy( currentskin, strchr( currentdirectory, '/' ) + 1 );
		Q_strncpyz( currentskin, strchr( currentdirectory, '/' ) + 1, sizeof(currentskin) );
		*strchr( currentdirectory, '/' ) = 0;
	}
	else if ( strchr( currentdirectory, '\\' ) )
	{
	//	strncpy( currentskin, strchr( currentdirectory, '\\' ) + 1 );
		Q_strncpyz( currentskin, strchr( currentdirectory, '\\' ) + 1, sizeof(currentskin) );
		*strchr( currentdirectory, '\\' ) = 0;
	}
	else
	{
	//	strncpy( currentdirectory, "male" );
	//	strncpy( currentskin, "grunt" );
		Q_strncpyz( currentdirectory, "male", sizeof(currentdirectory) );
		Q_strncpyz( currentskin, "grunt", sizeof(currentskin) );
	}

	qsort( s_pmi, s_numplayermodels, sizeof( s_pmi[0] ), pmicmpfnc );

	memset( s_pmnames, 0, sizeof( s_pmnames ) );
	for ( i = 0; i < s_numplayermodels; i++ )
	{
		s_pmnames[i] = s_pmi[i].displayname;
		if ( Q_stricmp( s_pmi[i].directory, currentdirectory ) == 0 )
		{
			int j;

			currentdirectoryindex = i;

			for ( j = 0; j < s_pmi[i].nskins; j++ )
			{
				if ( Q_stricmp( s_pmi[i].skindisplaynames[j], currentskin ) == 0 )
				{
					currentskinindex = j;
					break;
				}
			}
		}
	}
	
	s_player_config_menu.x = SCREEN_WIDTH*0.5 - 210;
	s_player_config_menu.y = SCREEN_HEIGHT*0.5 - 70;
	s_player_config_menu.nitems = 0;
	
	s_player_name_field.generic.type = MTYPE_FIELD;
	s_player_name_field.generic.flags = QMF_LEFT_JUSTIFY;
	s_player_name_field.generic.name = "name";
	s_player_name_field.generic.callback = 0;
	s_player_name_field.generic.x		= -MENU_FONT_SIZE;
	s_player_name_field.generic.y		= y;
	s_player_name_field.length	= 20;
	s_player_name_field.visible_length = 20;
	Q_strncpyz( s_player_name_field.buffer, name->string, sizeof(s_player_name_field.buffer) );
	s_player_name_field.cursor = strlen( name->string );
	
	s_player_model_title.generic.type = MTYPE_SEPARATOR;
	s_player_model_title.generic.flags = QMF_LEFT_JUSTIFY;
	s_player_model_title.generic.name = "model";
	s_player_model_title.generic.x    = -MENU_FONT_SIZE;
	s_player_model_title.generic.y	 = y += 3*MENU_LINE_SIZE;
	
	s_player_model_box.generic.type = MTYPE_SPINCONTROL;
	s_player_model_box.generic.x	= -7*MENU_FONT_SIZE;
	s_player_model_box.generic.y	= y += MENU_LINE_SIZE;
	s_player_model_box.generic.callback = ModelCallback;
	s_player_model_box.generic.cursor_offset = -6*MENU_FONT_SIZE;
	s_player_model_box.curvalue = currentdirectoryindex;
	s_player_model_box.itemnames = s_pmnames;
	
	s_player_skin_title.generic.type = MTYPE_SEPARATOR;
	s_player_skin_title.generic.flags = QMF_LEFT_JUSTIFY;
	s_player_skin_title.generic.name = "skin";
	s_player_skin_title.generic.x    = -2*MENU_FONT_SIZE;
	s_player_skin_title.generic.y	 = y += 2*MENU_LINE_SIZE;
	
	s_player_skin_box.generic.type = MTYPE_SPINCONTROL;
	s_player_skin_box.generic.x	= -7*MENU_FONT_SIZE;
	s_player_skin_box.generic.y	= y += MENU_LINE_SIZE;
	s_player_skin_box.generic.name	= 0;
	s_player_skin_box.generic.callback = SkinCallback; // Knightmare added, was 0
	s_player_skin_box.generic.cursor_offset = -6*MENU_FONT_SIZE;
	s_player_skin_box.curvalue = currentskinindex;
	s_player_skin_box.itemnames = s_pmi[currentdirectoryindex].skindisplaynames;
	s_player_skin_box.generic.flags |= QMF_SKINLIST;
	
	s_player_hand_title.generic.type = MTYPE_SEPARATOR;
	s_player_hand_title.generic.flags = QMF_LEFT_JUSTIFY;
	s_player_hand_title.generic.name = "handedness";
	s_player_hand_title.generic.x    = 4*MENU_FONT_SIZE;
	s_player_hand_title.generic.y	 = y += 2*MENU_LINE_SIZE;
	
	s_player_handedness_box.generic.type = MTYPE_SPINCONTROL;
	s_player_handedness_box.generic.x	= -7*MENU_FONT_SIZE;
	s_player_handedness_box.generic.y	= y += MENU_LINE_SIZE;
	s_player_handedness_box.generic.name	= 0;
	s_player_handedness_box.generic.cursor_offset = -6*MENU_FONT_SIZE;
	s_player_handedness_box.generic.callback = HandednessCallback;
	s_player_handedness_box.curvalue = Cvar_VariableValue( "hand" );
	s_player_handedness_box.itemnames = handedness;
	
	for (i = 0; i < sizeof(rate_tbl) / sizeof(*rate_tbl) - 1; i++)
		if (Cvar_VariableValue("rate") == rate_tbl[i])
			break;
		
	s_player_rate_title.generic.type = MTYPE_SEPARATOR;
	s_player_rate_title.generic.flags = QMF_LEFT_JUSTIFY;
	s_player_rate_title.generic.name = "connect speed";
	s_player_rate_title.generic.x    = 7*MENU_FONT_SIZE;
	s_player_rate_title.generic.y	 = y += 2*MENU_LINE_SIZE;
		
	s_player_rate_box.generic.type = MTYPE_SPINCONTROL;
	s_player_rate_box.generic.x	= -7*MENU_FONT_SIZE;
	s_player_rate_box.generic.y	= y += MENU_LINE_SIZE;
	s_player_rate_box.generic.name	= 0;
	s_player_rate_box.generic.cursor_offset = -6*MENU_FONT_SIZE;
	s_player_rate_box.generic.callback = RateCallback;
	s_player_rate_box.curvalue = i;
	s_player_rate_box.itemnames = rate_names;
	
	s_player_back_action.generic.type = MTYPE_ACTION;
	s_player_back_action.generic.name	= "back to multiplayer";
	s_player_back_action.generic.flags = QMF_LEFT_JUSTIFY;
	s_player_back_action.generic.x	= -5*MENU_FONT_SIZE;
	s_player_back_action.generic.y	= y += 2*MENU_LINE_SIZE;
	s_player_back_action.generic.statusbar = NULL;
	s_player_back_action.generic.callback = UI_BackMenu;

	// only register model and skin on starup or when changed
	Com_sprintf( scratch, sizeof( scratch ), "players/%s/tris.md2", s_pmi[s_player_model_box.curvalue].directory );
	playermodel = R_RegisterModel( scratch );

	Com_sprintf( scratch, sizeof( scratch ), "players/%s/%s.pcx", s_pmi[s_player_model_box.curvalue].directory, s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue] );
	playerskin = R_RegisterSkin( scratch );

	// show current weapon model (if any)
	if (currentweaponmodel && strlen(currentweaponmodel)) {
		Com_sprintf( scratch, sizeof( scratch ), "players/%s/%s", s_pmi[s_player_model_box.curvalue].directory, currentweaponmodel );
		weaponmodel = R_RegisterModel( scratch );
		if (!weaponmodel) {
			Com_sprintf( scratch, sizeof( scratch ), "players/%s/weapon.md2", s_pmi[s_player_model_box.curvalue].directory );
			weaponmodel = R_RegisterModel( scratch );
		}
	}
	else
	{
		Com_sprintf( scratch, sizeof( scratch ), "players/%s/weapon.md2", s_pmi[s_player_model_box.curvalue].directory );
		weaponmodel = R_RegisterModel( scratch );
	}

	Menu_AddItem( &s_player_config_menu, &s_player_name_field );
	Menu_AddItem( &s_player_config_menu, &s_player_model_title );
	Menu_AddItem( &s_player_config_menu, &s_player_model_box );
	if ( s_player_skin_box.itemnames )
	{
		Menu_AddItem( &s_player_config_menu, &s_player_skin_title );
		Menu_AddItem( &s_player_config_menu, &s_player_skin_box );
	}
	Menu_AddItem( &s_player_config_menu, &s_player_hand_title );
	Menu_AddItem( &s_player_config_menu, &s_player_handedness_box );
	Menu_AddItem( &s_player_config_menu, &s_player_rate_title );
	Menu_AddItem( &s_player_config_menu, &s_player_rate_box );
	Menu_AddItem( &s_player_config_menu, &s_player_back_action );

	return true;
}
Ejemplo n.º 11
0
/*
================
CL_LoadClientinfo

================
*/
void CL_LoadClientinfo (clientinfo_t *ci, char *s)
{
	int			i = 0;
	char		*t;
	char		model_name[MAX_QPATH];
	char		skin_name[MAX_QPATH];
	char		model_filename[MAX_QPATH];
	char		skin_filename[MAX_QPATH];
	char		weapon_filename[MAX_QPATH];

	Q_strncpyz (ci->cinfo, s, sizeof(ci->cinfo));

	// isolate the player's name
	Q_strncpyz (ci->name, s, sizeof(ci->name));

	t = strchr(s, '\\');
	if (t) {
		if (t - s >= sizeof(ci->name)-1) {
			i = -1;
		} else {
			ci->name[t-s] = 0;
			s = t+1;
		}
	}
	t = s;
	while (*t) {
		if (*t <= 32) {
			i = -1;
			break;
		}
		t++;
	}

	if (cl_noskins->integer || *s == 0 || i == -1)
	{
		strcpy (model_filename, "players/male/tris.md2");
		strcpy (weapon_filename, "players/male/weapon.md2");
		strcpy (skin_filename, "players/male/grunt.pcx");
		strcpy (ci->iconname, "/players/male/grunt_i.pcx");
		ci->model = R_RegisterModel (model_filename);
		memset(ci->weaponmodel, 0, sizeof(ci->weaponmodel));
		ci->weaponmodel[0] = R_RegisterModel (weapon_filename);
		ci->skin = R_RegisterSkin (skin_filename);
		ci->icon = Draw_FindPic (ci->iconname);
	}
	else
	{
		// isolate the model name
		Q_strncpyz (model_name, s, sizeof(model_name));
		t = strchr(model_name, '/');
		if (!t)
			t = strchr(model_name, '\\');
		
		if (!t) {
			memcpy (model_name, "male\0grunt\0\0\0\0\0\0", 16);
			s = "male\\grunt\0";
		}
		else {
			*t = 0;
		}

		// isolate the skin name
		Q_strncpyz(skin_name, s + strlen(model_name) + 1, sizeof(skin_name));

		// model file
		Com_sprintf (model_filename, sizeof(model_filename), "players/%s/tris.md2", model_name);
		ci->model = R_RegisterModel (model_filename);
		if (!ci->model)
		{
			strcpy(model_name, "male");
			strcpy(model_filename, "players/male/tris.md2");
			ci->model = R_RegisterModel (model_filename);
		}

		// skin file
		Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);
		ci->skin = R_RegisterSkin (skin_filename);

		// if we don't have the skin and the model wasn't male,
		// see if the male has it (this is for CTF's skins)
 		if (!ci->skin && Q_stricmp(model_name, "male"))
		{
			// change model to male
			strcpy(model_name, "male");
			strcpy(model_filename, "players/male/tris.md2");
			ci->model = R_RegisterModel (model_filename);

			// see if the skin exists for the male model
			Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);
			ci->skin = R_RegisterSkin (skin_filename);
		}

		// if we still don't have a skin, it means that the male model didn't have
		// it, so default to grunt
		if (!ci->skin) {
			// see if the skin exists for the male model
			Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/grunt.pcx", model_name);
			ci->skin = R_RegisterSkin (skin_filename);
		}

		// weapon file
		for (i = 0; i < num_cl_weaponmodels; i++) {
			Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/%s/%s", model_name, cl_weaponmodels[i]);
			ci->weaponmodel[i] = R_RegisterModel(weapon_filename);
			if (!ci->weaponmodel[i] && strcmp(model_name, "cyborg") == 0) {
				// try male
				Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/male/%s", cl_weaponmodels[i]);
				ci->weaponmodel[i] = R_RegisterModel(weapon_filename);
			}
			if (!cl_vwep->integer)
				break; // only one when vwep is off
		}

		// icon file
		Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/%s/%s_i.pcx", model_name, skin_name);
		ci->icon = Draw_FindPic (ci->iconname);
	}

	// must have loaded all data types to be valud
	if (!ci->skin || !ci->icon || !ci->model || !ci->weaponmodel[0])
	{
		ci->skin = NULL;
		ci->icon = NULL;
		ci->model = NULL;
		ci->weaponmodel[0] = NULL;
		return;
	}
}