Beispiel #1
0
byte *
SCR_ReadNextFrame(void)
{
    int r;
    int command;
    byte samples[22050 / 14 * 4];
    byte compressed[0x20000];
    int size;
    byte *pic;
    cblock_t in, huf1;
    int start, end, count;

    /* read the next frame */
    r = FS_FRead(&command, 4, 1, cl.cinematic_file);

    if (r == 0)
    {
        /* we'll give it one more chance */
        r = FS_FRead(&command, 4, 1, cl.cinematic_file);
    }

    if (r != 4)
    {
        return NULL;
    }

    command = LittleLong(command);

    if (command == 2)
    {
        return NULL;  /* last frame marker */
    }

    if (command == 1)
    {
        /* read palette */
        FS_Read(cl.cinematicpalette, sizeof(cl.cinematicpalette),
                cl.cinematic_file);
        cl.cinematicpalette_active = 0;
    }

    /* decompress the next frame */
    FS_Read(&size, 4, cl.cinematic_file);
    size = LittleLong(size);

    if (((unsigned long)size > sizeof(compressed)) || (size < 1))
    {
        Com_Error(ERR_DROP, "Bad compressed frame size");
    }

    FS_Read(compressed, size, cl.cinematic_file);

    /* read sound */
    start = cl.cinematicframe * cin.s_rate / 14;
    end = (cl.cinematicframe + 1) * cin.s_rate / 14;
    count = end - start;

    FS_Read(samples, count * cin.s_width * cin.s_channels,
            cl.cinematic_file);

    if (cin.s_width == 2)
    {
        for (r = 0; r < count * cin.s_channels; r++)
        {
            ((short *)samples)[r] = LittleShort(((short *)samples)[r]);
        }
    }

    S_RawSamples(count, cin.s_rate, cin.s_width, cin.s_channels,
                 samples, Cvar_VariableValue("s_volume"));

    in.data = compressed;
    in.count = size;

    huf1 = Huff1Decompress(in);

    pic = huf1.data;

    cl.cinematicframe++;

    return pic;
}
Beispiel #2
0
/*
====================
CL_ReadDemoMessage

Handles playback of demos
====================
*/
void CL_ReadDemoMessage(void)
{
	int i;
	float f;

	if (!cls.demoplayback)
		return;

	// LordHavoc: pausedemo
	if (cls.demopaused)
		return;

	for (;;)
	{
		// decide if it is time to grab the next message
		// always grab until fully connected
		if (cls.signon == SIGNONS)
		{
			if (cls.timedemo)
			{
				cls.td_frames++;
				cls.td_onesecondframes++;
				// if this is the first official frame we can now grab the real
				// td_starttime so the bogus time on the first frame doesn't
				// count against the final report
				if (cls.td_frames == 0)
				{
					cls.td_starttime = realtime;
					cls.td_onesecondnexttime = cl.time + 1;
					cls.td_onesecondrealtime = realtime;
					cls.td_onesecondframes = 0;
					cls.td_onesecondminfps = 0;
					cls.td_onesecondmaxfps = 0;
					cls.td_onesecondavgfps = 0;
					cls.td_onesecondavgcount = 0;
				}
				if (cl.time >= cls.td_onesecondnexttime)
				{
					double fps = cls.td_onesecondframes / (realtime - cls.td_onesecondrealtime);
					if (cls.td_onesecondavgcount == 0)
					{
						cls.td_onesecondminfps = fps;
						cls.td_onesecondmaxfps = fps;
					}
					cls.td_onesecondrealtime = realtime;
					cls.td_onesecondminfps = min(cls.td_onesecondminfps, fps);
					cls.td_onesecondmaxfps = max(cls.td_onesecondmaxfps, fps);
					cls.td_onesecondavgfps += fps;
					cls.td_onesecondavgcount++;
					cls.td_onesecondframes = 0;
					cls.td_onesecondnexttime++;
				}
			}
			else if (cl.time <= cl.mtime[0])
			{
				// don't need another message yet
				return;
			}
		}

		// get the next message
		FS_Read(cls.demofile, &cl_message.cursize, 4);
		cl_message.cursize = LittleLong(cl_message.cursize);
		if(cl_message.cursize & DEMOMSG_CLIENT_TO_SERVER) // This is a client->server message! Ignore for now!
		{
			// skip over demo packet
			FS_Seek(cls.demofile, 12 + (cl_message.cursize & (~DEMOMSG_CLIENT_TO_SERVER)), SEEK_CUR);
			continue;
		}
		if (cl_message.cursize > cl_message.maxsize)
		{
			Con_Printf("Demo message (%i) > cl_message.maxsize (%i)", cl_message.cursize, cl_message.maxsize);
			cl_message.cursize = 0;
			CL_Disconnect();
			return;
		}
		VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
		for (i = 0;i < 3;i++)
		{
			FS_Read(cls.demofile, &f, 4);
			cl.mviewangles[0][i] = LittleFloat(f);
		}

		if (FS_Read(cls.demofile, cl_message.data, cl_message.cursize) == cl_message.cursize)
		{
			MSG_BeginReading(&cl_message);
			CL_ParseServerMessage();

			if (cls.signon != SIGNONS)
				Cbuf_Execute(); // immediately execute svc_stufftext if in the demo before connect!

			// In case the demo contains a "svc_disconnect" message
			if (!cls.demoplayback)
				return;

			if (cls.timedemo)
				return;
		}
		else
		{
			CL_Disconnect();
			return;
		}
	}
}
Beispiel #3
0
int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) {
   return FS_Read( buffer, size * count, f );
}
Beispiel #4
0
static demoPlay_t *demoPlayOpen( const char* fileName ) {
	demoPlay_t	*play;
	fileHandle_t fileHandle;
	int	fileSize, filePos;
	int i;

	msg_t msg;
	fileSize = FS_FOpenFileRead( fileName, &fileHandle, qtrue );
	if (fileHandle<=0) {
		Com_Printf("Failed to open demo file %s \n", fileName );
		return 0;
	}
	filePos = strlen( demoHeader );
	i = FS_Read( &demoBuffer, filePos, fileHandle );
	if ( i != filePos || Q_strncmp( demoBuffer, demoHeader, filePos )) {
		Com_Printf("demo file %s is wrong version\n", fileName );
		FS_FCloseFile( fileHandle );
		return 0;
	}
	play = Z_Malloc( sizeof( demoPlay_t ));
	Q_strncpyz( play->fileName, fileName, sizeof( play->fileName ));
	play->fileSize = fileSize;
	play->frame = &play->storageFrame[0];
	play->nextFrame = &play->storageFrame[1];
	for (i=0;i<DEMO_PLAY_CMDS;i++)
		play->commandStart[i] = i;
	play->commandFree = DEMO_PLAY_CMDS;

	for ( ; filePos<fileSize; ) {
		int blockSize, isFull, serverTime;
		FS_Read( &blockSize, 4, fileHandle );
		blockSize = LittleLong( blockSize );
		if (blockSize > sizeof(demoBuffer)) {
			Com_Printf( "Block too large to be read in.\n");
			goto errorreturn;
		}
		if ( blockSize + filePos > fileSize) {
			Com_Printf( "Block would read past the end of the file.\n");
			goto errorreturn;
		}
		FS_Read( demoBuffer, blockSize, fileHandle );
		MSG_Init( &msg, demoBuffer, sizeof(demoBuffer) );
		MSG_BeginReading( &msg );
		msg.cursize = blockSize;	
		isFull = MSG_ReadBits( &msg, 1 );
		serverTime = MSG_ReadLong( &msg );
		if (!play->startTime)
			play->startTime = serverTime;
		if (isFull) {
			if (play->fileIndexCount < DEMO_MAX_INDEX) {
				play->fileIndex[play->fileIndexCount].pos = filePos;
				play->fileIndex[play->fileIndexCount].frame = play->totalFrames;
				play->fileIndex[play->fileIndexCount].time = serverTime;
				play->fileIndexCount++;
			}
		}
		play->endTime = serverTime;
		filePos += 4 + blockSize;
		play->totalFrames++;
	}
	play->fileHandle = fileHandle;
	demoPlaySetIndex( play, 0 );
	play->clientNum = -1;
	for( i=0;i<MAX_CLIENTS;i++)
		if (play->frame->clientData[i]) {
			play->clientNum = i;
			break;
		}
	return play;
errorreturn:
	Z_Free( play );
	FS_FCloseFile( fileHandle );
	return 0;
}
Beispiel #5
0
int CL_CgameSystemCalls( int *args ) {
	switch( args[0] ) {
	case CG_PRINT:
		Com_Printf( "%s", VMA(1) );
		return 0;
	case CG_ERROR:
		Com_Error( ERR_DROP, S_COLOR_RED"%s", VMA(1) );
		return 0;
	case CG_MILLISECONDS:
		return Sys_Milliseconds();
	case CG_CVAR_REGISTER:
		Cvar_Register( (vmCvar_t *) VMA(1), (const char *) VMA(2), (const char *) VMA(3), args[4] ); 
		return 0;
	case CG_CVAR_UPDATE:
		Cvar_Update( (vmCvar_t *) VMA(1) );
		return 0;
	case CG_CVAR_SET:
		Cvar_Set( (const char *) VMA(1), (const char *) VMA(2) );
		return 0;
	case CG_ARGC:
		return Cmd_Argc();
	case CG_ARGV:
		Cmd_ArgvBuffer( args[1], (char *) VMA(2), args[3] );
		return 0;
	case CG_ARGS:
		Cmd_ArgsBuffer( (char *) VMA(1), args[2] );
		return 0;
	case CG_FS_FOPENFILE:
		return FS_FOpenFileByMode( (const char *) VMA(1), (int *) VMA(2), (fsMode_t) args[3] );
	case CG_FS_READ:
		FS_Read( VMA(1), args[2], args[3] );
		return 0;
	case CG_FS_WRITE:
		FS_Write( VMA(1), args[2], args[3] );
		return 0;
	case CG_FS_FCLOSEFILE:
		FS_FCloseFile( args[1] );
		return 0;
	case CG_SENDCONSOLECOMMAND:
		Cbuf_AddText( (const char *) VMA(1) );
		return 0;
	case CG_ADDCOMMAND:
		CL_AddCgameCommand( (const char *) VMA(1) );
		return 0;
	case CG_SENDCLIENTCOMMAND:
		CL_AddReliableCommand( (const char *) VMA(1) );
		return 0;
	case CG_UPDATESCREEN:
		// this is used during lengthy level loading, so pump message loop
		Com_EventLoop();	// FIXME: if a server restarts here, BAD THINGS HAPPEN!
		SCR_UpdateScreen();
		return 0;

#ifdef _XBOX
	case CG_RMG_INIT:
	case CG_CM_REGISTER_TERRAIN:
	case CG_RE_INIT_RENDERER_TERRAIN:
		Com_Error( ERR_FATAL, "ERROR: Terrain unsupported on Xbox.\n" );
#else
	case CG_RMG_INIT:
		/*
		if (!com_sv_running->integer)
		{	// don't do this if we are connected locally
			if (!TheRandomMissionManager)
			{
				TheRandomMissionManager = new CRMManager;
			}
			TheRandomMissionManager->SetLandScape( cmg.landScapes[args[1]] );
			TheRandomMissionManager->LoadMission(qfalse);
			TheRandomMissionManager->SpawnMission(qfalse);
			cmg.landScapes[args[1]]->UpdatePatches();
		}
		*/ //this is SP.. I guess we're always the client and server.
//		cl.mRMGChecksum = cm.landScapes[args[1]]->get_rand_seed();
		RM_CreateRandomModels(args[1], (const char *)VMA(2));
		//cmg.landScapes[args[1]]->rand_seed(cl.mRMGChecksum);		// restore it, in case we do a vid restart
		cmg.landScape->rand_seed(cmg.landScape->get_rand_seed());
//		TheRandomMissionManager->CreateMap();
		return 0;
	case CG_CM_REGISTER_TERRAIN:
		return CM_RegisterTerrain((const char *)VMA(1), false)->GetTerrainId();

	case CG_RE_INIT_RENDERER_TERRAIN:
		RE_InitRendererTerrain((const char *)VMA(1));
		return 0;
#endif	// _XBOX

	case CG_CM_LOADMAP:
#ifdef _XBOX
		CL_CM_LoadMap( (const char *) VMA(1) );
#else
		CL_CM_LoadMap( (const char *) VMA(1), args[2] );
#endif
		return 0;
	case CG_CM_NUMINLINEMODELS:
		return CM_NumInlineModels();
	case CG_CM_INLINEMODEL:
		return CM_InlineModel( args[1] );
	case CG_CM_TEMPBOXMODEL:
		return CM_TempBoxModel( (const float *) VMA(1), (const float *) VMA(2) );//, (int) VMA(3) );
	case CG_CM_POINTCONTENTS:
		return CM_PointContents( (float *)VMA(1), args[2] );
	case CG_CM_TRANSFORMEDPOINTCONTENTS:
		return CM_TransformedPointContents( (const float *) VMA(1), args[2], (const float *) VMA(3), (const float *) VMA(4) );
	case CG_CM_BOXTRACE:
		CM_BoxTrace( (trace_t *) VMA(1), (const float *) VMA(2), (const float *) VMA(3), (const float *) VMA(4), (const float *) VMA(5), args[6], args[7] );
		return 0;
	case CG_CM_TRANSFORMEDBOXTRACE:
		CM_TransformedBoxTrace( (trace_t *) VMA(1), (const float *) VMA(2), (const float *) VMA(3), (const float *) VMA(4), (const float *) VMA(5), args[6], args[7], (const float *) VMA(8), (const float *) VMA(9) );
		return 0;
	case CG_CM_MARKFRAGMENTS:
		return re.MarkFragments( args[1], (float(*)[3]) VMA(2), (const float *) VMA(3), args[4], (float *) VMA(5), args[6], (markFragment_t *) VMA(7) );
	case CG_CM_SNAPPVS:
		CM_SnapPVS((float(*))VMA(1),(byte *) VMA(2));
		return 0;
	case CG_S_STOPSOUNDS:
		S_StopSounds( );
		return 0;

	case CG_S_STARTSOUND:
		// stops an ERR_DROP internally if called illegally from game side, but note that it also gets here 
		//	legally during level start where normally the internal s_soundStarted check would return. So ok to hit this.
		if (!cls.cgameStarted){
			return 0;	
		}
		S_StartSound( (float *) VMA(1), args[2], (soundChannel_t)args[3], args[4] );
		return 0;
	case CG_S_UPDATEAMBIENTSET:
		// stops an ERR_DROP internally if called illegally from game side, but note that it also gets here 
		//	legally during level start where normally the internal s_soundStarted check would return. So ok to hit this.
		if (!cls.cgameStarted){
			return 0;
		}
		S_UpdateAmbientSet( (const char *) VMA(1), (float *) VMA(2) );
		return 0;
	case CG_S_ADDLOCALSET:
		return S_AddLocalSet( (const char *) VMA(1), (float *) VMA(2), (float *) VMA(3), args[4], args[5] );
	case CG_AS_PARSESETS:
		AS_ParseSets();
		return 0;
	case CG_AS_ADDENTRY:
		AS_AddPrecacheEntry( (const char *) VMA(1) );
		return 0;
	case CG_AS_GETBMODELSOUND:
		return AS_GetBModelSound( (const char *) VMA(1), args[2] );	
	case CG_S_STARTLOCALSOUND:
		// stops an ERR_DROP internally if called illegally from game side, but note that it also gets here 
		//	legally during level start where normally the internal s_soundStarted check would return. So ok to hit this.
		if (!cls.cgameStarted){
			return 0;
		}
		S_StartLocalSound( args[1], args[2] );
		return 0;
	case CG_S_CLEARLOOPINGSOUNDS:
		S_ClearLoopingSounds();
		return 0;
	case CG_S_ADDLOOPINGSOUND:
		// stops an ERR_DROP internally if called illegally from game side, but note that it also gets here 
		//	legally during level start where normally the internal s_soundStarted check would return. So ok to hit this.
		if (!cls.cgameStarted){
			return 0;
		}
		S_AddLoopingSound( args[1], (const float *) VMA(2), (const float *) VMA(3), args[4], (soundChannel_t)args[5] );
		return 0;
	case CG_S_UPDATEENTITYPOSITION:
		S_UpdateEntityPosition( args[1], (const float *) VMA(2) );
		return 0;
	case CG_S_RESPATIALIZE:
		S_Respatialize( args[1], (const float *) VMA(2), (float(*)[3]) VMA(3), args[4] );
		return 0;
	case CG_S_REGISTERSOUND:
		return S_RegisterSound( (const char *) VMA(1) );
	case CG_S_STARTBACKGROUNDTRACK:
		S_StartBackgroundTrack( (const char *) VMA(1), (const char *) VMA(2), args[3]);
		return 0;
	case CG_S_GETSAMPLELENGTH:
		return S_GetSampleLengthInMilliSeconds(  args[1]);
#ifdef _IMMERSION
	case CG_FF_START:
		CL_FF_Start( (ffHandle_t) args[1], (int) args[2] );
		return 0;
	case CG_FF_STOP:
		CL_FF_Stop( (ffHandle_t) args[1], (int) args[2] );
		return 0;
	case CG_FF_STOPALL:
		FF_StopAll();
		return 0;
	case CG_FF_SHAKE:
		FF_Shake( (int) args[1], (int) args[2] );
		return 0;
	case CG_FF_REGISTER:
		return FF_Register( (const char *) VMA(1), (int) args[2] );
	case CG_FF_ADDLOOPINGFORCE:
		CL_FF_AddLoopingForce( (ffHandle_t) args[1], (int) args[2] );
		return 0;
#else
	case CG_FF_STARTFX:
		FFFX_START( (ffFX_e) args[1] );
		return 0;
	case CG_FF_ENSUREFX:
		FFFX_ENSURE( (ffFX_e) args[1] );
		return 0;
	case CG_FF_STOPFX:
		FFFX_STOP( (ffFX_e) args[1] );
		return 0;
	case CG_FF_STOPALLFX:
		FFFX_STOPALL;
		return 0;
#endif // _IMMERSION
#ifdef _XBOX
	case CG_FF_XBOX_SHAKE:
		FF_XboxShake( VMF(1), (int) args[2] );
		return 0;
	case CG_FF_XBOX_DAMAGE:
		FF_XboxDamage( (int) args[1], VMF(2) );
		return 0;
#endif
	case CG_R_LOADWORLDMAP:
		re.LoadWorld( (const char *) VMA(1) );
		return 0; 
	case CG_R_REGISTERMODEL:
		return re.RegisterModel( (const char *) VMA(1) );
	case CG_R_REGISTERSKIN:
		return re.RegisterSkin( (const char *) VMA(1) );
	case CG_R_REGISTERSHADER:
		return re.RegisterShader( (const char *) VMA(1) );
	case CG_R_REGISTERSHADERNOMIP:
		return re.RegisterShaderNoMip( (const char *) VMA(1) );
	case CG_R_REGISTERFONT:
		return re.RegisterFont( (const char *) VMA(1) );
	case CG_R_FONTSTRLENPIXELS:
		return re.Font_StrLenPixels( (const char *) VMA(1), args[2], VMF(3) );
	case CG_R_FONTSTRLENCHARS:
		return re.Font_StrLenChars( (const char *) VMA(1) );
	case CG_R_FONTHEIGHTPIXELS:
		return re.Font_HeightPixels( args[1], VMF(2) );
	case CG_R_FONTDRAWSTRING:
		re.Font_DrawString(args[1],args[2], (const char *) VMA(3), (float*)args[4], args[5], args[6], VMF(7));
		return 0;
	case CG_LANGUAGE_ISASIAN:
		return re.Language_IsAsian();
	case CG_LANGUAGE_USESSPACES:
		return re.Language_UsesSpaces();
	case CG_ANYLANGUAGE_READFROMSTRING:
		return re.AnyLanguage_ReadCharFromString( (const char *) VMA(1), (int *) VMA(2), (qboolean *) VMA(3) );
	case CG_R_SETREFRACTIONPROP:
		tr_distortionAlpha = VMF(1);
		tr_distortionStretch = VMF(2);
		tr_distortionPrePost = (qboolean)args[3];
		tr_distortionNegate = (qboolean)args[4];
		return 0;
	case CG_R_CLEARSCENE:
		re.ClearScene();
		return 0;
	case CG_R_ADDREFENTITYTOSCENE:
		re.AddRefEntityToScene( (const refEntity_t *) VMA(1) );
		return 0;

	case CG_R_INPVS:
		return R_inPVS((float *) VMA(1), (float *) VMA(2));

	case CG_R_GETLIGHTING:
		return re.GetLighting( (const float * ) VMA(1), (float *) VMA(2), (float *) VMA(3), (float *) VMA(4) );
	case CG_R_ADDPOLYTOSCENE:
		re.AddPolyToScene( args[1], args[2], (const polyVert_t *) VMA(3) );
		return 0;
	case CG_R_ADDLIGHTTOSCENE:
#ifdef VV_LIGHTING
		VVLightMan.RE_AddLightToScene ( (const float *) VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
#else
		re.AddLightToScene( (const float *) VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
#endif
		return 0;
	case CG_R_RENDERSCENE:
		re.RenderScene( (const refdef_t *) VMA(1) );
		return 0;
	case CG_R_SETCOLOR:
		re.SetColor( (const float *) VMA(1) );
		return 0;
	case CG_R_DRAWSTRETCHPIC:
		re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9] );
		return 0;
	//case CG_R_DRAWSCREENSHOT:
	//	re.DrawStretchRaw( VMF(1), VMF(2), VMF(3), VMF(4), SG_SCR_WIDTH, SG_SCR_HEIGHT, SCR_GetScreenshot(0), 0, qtrue);
	//	return 0;
	case CG_R_MODELBOUNDS:
		re.ModelBounds( args[1], (float *) VMA(2), (float *) VMA(3) );
		return 0;
	case CG_R_LERPTAG:
		re.LerpTag( (orientation_t *) VMA(1), args[2], args[3], args[4], VMF(5), (const char *) VMA(6) );
		return 0;
	case CG_R_DRAWROTATEPIC:
		re.DrawRotatePic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), VMF(9), args[10] );
		return 0;
	case CG_R_DRAWROTATEPIC2:
		re.DrawRotatePic2( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), VMF(9), args[10] );
		return 0;
	case CG_R_SETRANGEFOG:
		if (tr.rangedFog <= 0.0f)
		{
			g_oldRangedFog = tr.rangedFog;
		}
		tr.rangedFog = VMF(1);
		if (tr.rangedFog == 0.0f && g_oldRangedFog)
		{ //restore to previous state if applicable
			tr.rangedFog = g_oldRangedFog;
		}
		return 0;
	case CG_R_LA_GOGGLES:
		re.LAGoggles();
		return 0;
	case CG_R_SCISSOR:
		re.Scissor( VMF(1), VMF(2), VMF(3), VMF(4));
		return 0;
	case CG_GETGLCONFIG:
		CL_GetGlconfig( (glconfig_t *) VMA(1) );
		return 0;
	case CG_GETGAMESTATE:
		CL_GetGameState( (gameState_t *) VMA(1) );
		return 0;
	case CG_GETCURRENTSNAPSHOTNUMBER:
		CL_GetCurrentSnapshotNumber( (int *) VMA(1), (int *) VMA(2) );
		return 0;
	case CG_GETSNAPSHOT:
		return CL_GetSnapshot( args[1], (snapshot_t *) VMA(2) );

	case CG_GETDEFAULTSTATE:
		return CL_GetDefaultState(args[1], (entityState_t *)VMA(2));

	case CG_GETSERVERCOMMAND:
		return CL_GetServerCommand( args[1] );
	case CG_GETCURRENTCMDNUMBER:
		return CL_GetCurrentCmdNumber();
	case CG_GETUSERCMD:
		return CL_GetUserCmd( args[1], (usercmd_s *) VMA(2) );
	case CG_SETUSERCMDVALUE:
		CL_SetUserCmdValue( args[1], VMF(2), VMF(3), VMF(4) );
		return 0;
	case CG_SETUSERCMDANGLES:
		CL_SetUserCmdAngles( VMF(1), VMF(2), VMF(3) );
		return 0;
	case COM_SETORGANGLES:
		Com_SetOrgAngles((float *)VMA(1),(float *)VMA(2));
		return 0;
/*
Ghoul2 Insert Start
*/
		
	case CG_G2_LISTSURFACES:
		G2API_ListSurfaces( (CGhoul2Info *) VMA(1) );
		return 0;

	case CG_G2_LISTBONES:
		G2API_ListBones( (CGhoul2Info *) VMA(1), args[2]);
		return 0;

	case CG_G2_HAVEWEGHOULMODELS:
		return G2API_HaveWeGhoul2Models( *((CGhoul2Info_v *)VMA(1)) );

	case CG_G2_SETMODELS:
		G2API_SetGhoul2ModelIndexes( *((CGhoul2Info_v *)VMA(1)),(qhandle_t *)VMA(2),(qhandle_t *)VMA(3));
		return 0;

/*
Ghoul2 Insert End
*/

	case CG_R_GET_LIGHT_STYLE:
		re.GetLightStyle(args[1], (byte*) VMA(2) );
		return 0;
	case CG_R_SET_LIGHT_STYLE:
		re.SetLightStyle(args[1], args[2] );
		return 0;

	case CG_R_GET_BMODEL_VERTS:
		re.GetBModelVerts( args[1], (float (*)[3])VMA(2), (float *)VMA(3) );
		return 0;
	
	case CG_R_WORLD_EFFECT_COMMAND:
		re.WorldEffectCommand( (const char *) VMA(1) );
		return 0;

	case CG_CIN_PLAYCINEMATIC:
	  return CIN_PlayCinematic( (const char *) VMA(1), args[2], args[3], args[4], args[5], args[6], (const char *) VMA(7));

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

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

#ifndef _XBOX
	case CG_CIN_DRAWCINEMATIC:
	  CIN_DrawCinematic(args[1]);
	  return 0;
#endif

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

	case CG_Z_MALLOC:
		return (int)Z_Malloc(args[1], (memtag_t) args[2], qfalse);

	case CG_Z_FREE:
		Z_Free((void *) VMA(1));
		return 0;

	case CG_UI_SETACTIVE_MENU:
		UI_SetActiveMenu((const char *) VMA(1),NULL);
		return 0;

	case CG_UI_MENU_OPENBYNAME:
		Menus_OpenByName((const char *) VMA(1));
		return 0;

	case CG_UI_MENU_RESET:
		Menu_Reset();
		return 0;

	case CG_UI_MENU_NEW:
		Menu_New((char *) VMA(1));
		return 0;

	case CG_UI_PARSE_INT:
		PC_ParseInt((int *) VMA(1));
		return 0;

	case CG_UI_PARSE_STRING:
		PC_ParseString((const char **) VMA(1));
		return 0;

	case CG_UI_PARSE_FLOAT:
		PC_ParseFloat((float *) VMA(1));
		return 0;

	case CG_UI_STARTPARSESESSION:
		return(PC_StartParseSession((char *) VMA(1),(char **) VMA(2)));

	case CG_UI_ENDPARSESESSION:
		PC_EndParseSession((char *) VMA(1));
		return 0;

	case CG_UI_PARSEEXT:
		char **holdPtr;

		holdPtr = (char **) VMA(1);
		*holdPtr = PC_ParseExt();
		return 0;

	case CG_UI_MENUCLOSE_ALL:
		Menus_CloseAll();
		return 0;

	case CG_UI_MENUPAINT_ALL:
		Menu_PaintAll();
		return 0;

	case CG_UI_STRING_INIT:
		String_Init();
		return 0;

	case CG_UI_GETMENUINFO:
		menuDef_t *menu;
		int		*xPos,*yPos,*w,*h,result;

		menu = Menus_FindByName((char *) VMA(1));	// Get menu 
		if (menu)
		{
			xPos = (int *) VMA(2);
			*xPos = (int) menu->window.rect.x;
			yPos = (int *) VMA(3);
			*yPos = (int) menu->window.rect.y;
			w = (int *) VMA(4);
			*w = (int) menu->window.rect.w;
			h = (int *) VMA(5);
			*h = (int) menu->window.rect.h;
			result = qtrue;
		}
		else
		{
			result = qfalse;
		}

		return result;

	case CG_UI_GETITEMTEXT:
		itemDef_t *item;
		menu = Menus_FindByName((char *) VMA(1));	// Get menu 

		if (menu)
		{
			item = (itemDef_s *) Menu_FindItemByName((menuDef_t *) menu, (char *) VMA(2));
			if (item)
			{
				Q_strncpyz( (char *) VMA(3), item->text, 256 );
				result = qtrue;
			}
			else
			{
				result = qfalse;
			}
		}
		else
		{
			result = qfalse;
		}

		return result;

	case CG_UI_GETITEMINFO:
		menu = Menus_FindByName((char *) VMA(1));	// Get menu 

		if (menu)
		{
			qhandle_t *background;

			item = (itemDef_s *) Menu_FindItemByName((menuDef_t *) menu, (char *) VMA(2));
			if (item)
			{
				xPos = (int *) VMA(3);
				*xPos = (int) item->window.rect.x;
				yPos = (int *) VMA(4);
				*yPos = (int) item->window.rect.y;
				w = (int *) VMA(5);
				*w = (int) item->window.rect.w;
				h = (int *) VMA(6);
				*h = (int) item->window.rect.h;

				vec4_t *color;

				color = (vec4_t *) VMA(7);
				if (!color)
				{
					return qfalse;
				}

				(*color)[0] = (float) item->window.foreColor[0];
				(*color)[1] = (float) item->window.foreColor[1];
				(*color)[2] = (float) item->window.foreColor[2];
				(*color)[3] = (float) item->window.foreColor[3];
				background = (qhandle_t *) VMA(8);
				if (!background)
				{
					return qfalse;
				}
				*background = item->window.background;

				result = qtrue;
			}
			else
			{
				result = qfalse;
			}
		}
		else
		{
			result = qfalse;
		}

		return result;
		
	case CG_SP_GETSTRINGTEXTSTRING:
		const char* text;

		assert(VMA(1));	
		text = SE_GetString( (const char *) VMA(1) );

		if (VMA(2))	// only if dest buffer supplied...
		{
			if ( text[0] )
			{
				Q_strncpyz( (char *) VMA(2), text, args[3] );				
			}
			else 
			{
				Com_sprintf( (char *) VMA(2), args[3], "??%s", VMA(1) );
			}
		}
		return strlen(text);
		//break;
	default:
		Com_Error( ERR_DROP, "Bad cgame system trap: %i", args[0] );
	}
	return 0;
}
/*
====================
CL_UpdateLevelHunkUsage

  This updates the "hunkusage.dat" file with the current map and it's hunk usage count

  This is used for level loading, so we can show a percentage bar dependant on the amount
  of hunk memory allocated so far

  This will be slightly inaccurate if some settings like sound quality are changed, but these
  things should only account for a small variation (hopefully)
====================
*/
void CL_UpdateLevelHunkUsage( void ) {
	int handle;
	char *memlistfile = "hunkusage.dat";
	char *buf, *outbuf;
	char *buftrav, *outbuftrav;
	char *token;
	char outstr[256];
	int len, memusage;

	memusage = Cvar_VariableIntegerValue( "com_hunkused" ) + Cvar_VariableIntegerValue( "hunk_soundadjust" );

	len = FS_FOpenFileByMode( memlistfile, &handle, FS_READ );
	if ( len >= 0 ) { // the file exists, so read it in, strip out the current entry for this map, and save it out, so we can append the new value

		buf = (char *)Z_Malloc( len + 1 );
		memset( buf, 0, len + 1 );
		outbuf = (char *)Z_Malloc( len + 1 );
		memset( outbuf, 0, len + 1 );

		FS_Read( (void *)buf, len, handle );
		FS_FCloseFile( handle );

		// now parse the file, filtering out the current map
		buftrav = buf;
		outbuftrav = outbuf;
		outbuftrav[0] = '\0';
		while ( ( token = COM_Parse( &buftrav ) ) && token[0] ) {
			if ( !Q_strcasecmp( token, cl.mapname ) ) {
				// found a match
				token = COM_Parse( &buftrav );  // read the size
				if ( token && token[0] ) {
					if ( atoi( token ) == memusage ) {  // if it is the same, abort this process
						Z_Free( buf );
						Z_Free( outbuf );
						return;
					}
				}
			} else {    // send it to the outbuf
				Q_strcat( outbuftrav, len + 1, token );
				Q_strcat( outbuftrav, len + 1, " " );
				token = COM_Parse( &buftrav );  // read the size
				if ( token && token[0] ) {
					Q_strcat( outbuftrav, len + 1, token );
					Q_strcat( outbuftrav, len + 1, "\n" );
				} else {
					Com_Error( ERR_DROP, "hunkusage.dat file is corrupt\n" );
				}
			}
		}

#ifdef __MACOS__    //DAJ MacOS file typing
		{
			extern _MSL_IMP_EXP_C long _fcreator, _ftype;
			_ftype = 'TEXT';
			_fcreator = 'WlfS';
		}
#endif
		handle = FS_FOpenFileWrite( memlistfile );
		if ( handle < 0 ) {
			Com_Error( ERR_DROP, "cannot create %s\n", memlistfile );
		}
		// input file is parsed, now output to the new file
		len = strlen( outbuf );
		if ( FS_Write( (void *)outbuf, len, handle ) != len ) {
			Com_Error( ERR_DROP, "cannot write to %s\n", memlistfile );
		}
		FS_FCloseFile( handle );

		Z_Free( buf );
		Z_Free( outbuf );
	}
	// now append the current map to the current file
	FS_FOpenFileByMode( memlistfile, &handle, FS_APPEND );
	if ( handle < 0 ) {
		Com_Error( ERR_DROP, "cannot write to hunkusage.dat, check disk full\n" );
	}
	Com_sprintf( outstr, sizeof( outstr ), "%s %i\n", cl.mapname, memusage );
	FS_Write( outstr, strlen( outstr ), handle );
	FS_FCloseFile( handle );

	// now just open it and close it, so it gets copied to the pak dir
	len = FS_FOpenFileByMode( memlistfile, &handle, FS_READ );
	if ( len >= 0 ) {
		FS_FCloseFile( handle );
	}
}
Beispiel #7
0
void loadNativePNG(texture_t* tmpTex)
{
	png_structp     png_ptr;
	png_infop       info_ptr;
	unsigned int    width;
	unsigned int    height;
	int             i;

	int             bit_depth;
	int             color_type ;
	png_size_t      rowbytes;
	png_bytep       *row_pointers;
	png_byte header[8];


/*
 * char realPath[1024];
  memset(realPath, 0, 1024);
  strcat(realPath, FS_Gamedir());
  if (tmpTex->path[0] != '/')
	strcat(realPath, "/");
  strcat(realPath, tmpTex->path);
*/
  tmpTex->format = TEXTURE_TYPE_UNKNOWN ;

  file = FS_OpenFile(tmpTex->path, "rb");

  //LOGI("[Android Main] Opening %s", realPath);

	if ( !file  )
		abort_textureLoading_("[read_png_file] Could not open file '%s'\n",tmpTex->path);

	FS_Read(header,1, 8,file);

	if (png_sig_cmp(header, 0, 8) != 0 )
		abort_textureLoading_("[read_png_file] File is not recognized as a PNG file.\n", tmpTex->path);

	// initialize
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

	if (png_ptr == NULL)
		abort_textureLoading_("[read_png_file] png_create_read_struct failed","");

	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL)
		abort_textureLoading_("[read_png_file] png_create_info_struct failed","");

	if (setjmp(png_jmpbuf(png_ptr)))
		abort_textureLoading_("[read_png_file] Error during init_io","");

	png_set_read_fn(png_ptr, NULL, png_zip_read);
	png_set_sig_bytes(png_ptr, 8);

	png_read_info(png_ptr, info_ptr);

  //Retrieve metadata and transfer to structure bean tmpTex
	png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);

	tmpTex->width = width;
	tmpTex->height =  height;

	// Set up some transforms.
	/*if (color_type & PNG_COLOR_MASK_ALPHA) {
		png_set_strip_alpha(png_ptr);
	}*/
	if (bit_depth > 8) {
		png_set_strip_16(png_ptr);
	}
	if (color_type == PNG_COLOR_TYPE_GRAY ||
		color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
		png_set_gray_to_rgb(png_ptr);
	}
	if (color_type == PNG_COLOR_TYPE_PALETTE) {
		png_set_palette_to_rgb(png_ptr);
	}

	// Update the png info struct.
	png_read_update_info(png_ptr, info_ptr);

	// Rowsize in bytes.
	rowbytes = png_get_rowbytes(png_ptr, info_ptr);

  	tmpTex->bpp = rowbytes / width;
	if (tmpTex->bpp == 4)
		tmpTex->format = TEXTURE_GL_RGBA;
	else
		tmpTex->format = TEXTURE_GL_RGB;

	Log_Printf("DEBUG: For %s, bpp: %i, color_type: %i, bit_depth: %i", tmpTex->path, tmpTex->bpp, color_type, bit_depth);
  //Since PNG can only store one image there is only one mipmap, allocated an array of one
  tmpTex->numMipmaps = 1;
  tmpTex->data = malloc(sizeof(uchar*));
	if ((tmpTex->data[0] = (uchar*)malloc(rowbytes * height))==NULL)
  {
	//Oops texture won't be able to hold the result :(, cleanup LIBPNG internal state and return;
	free(tmpTex->data);
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	return;
	}

  //Next we need to send to libpng an array of pointer, let's point to tmpTex->data[0]
	if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL)
  {
	// Oops looks like we won't have enough RAM to allocate an array of pointer....
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		free(tmpTex->data );
		tmpTex->data  = NULL;
	return;
	}

  //FCS: Hm, it looks like we are flipping the image vertically.
  //     Since iOS did not do it, we may have to not to that. If result is
  //     messed up, just swap to:   row_pointers[             i] = ....
	for (i = 0;  i < height;  ++i)
		//row_pointers[height - 1 - i] = tmpTex->data[0]  + i * rowbytes;
	row_pointers[             i] = tmpTex->data[0]  + i*rowbytes;


  //Decompressing PNG to RAW where row_pointers are pointing (tmpTex->data[0])
	png_read_image(png_ptr, row_pointers);

  //Last but not least:


	// Free LIBPNG internal state.
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

  //Free the decompression buffer
  free(row_pointers);

  FS_CloseFile(file);
}
kal_int32 SDS_NvramSupportTest(void)
{
   #define TEST_IDX 123
   kal_int32 status;
   const kal_uint16 *filelist[] = {L"test0", L"test1", L"test2", L"test3"};
   const kal_uint16 *dirlist[] = {L"Z:", L"Z:", L"Z:", L"Z:"};
   const kal_uint32  filesize[] = {0, 2048, 4097, 128*1024};

   kal_int32 fd, fsRet = 0, i, j;
   kal_uint32 toWrite, writtenLen;
   kal_uint32 toRead, readLen;   

   for(i=0; i<sizeof(filelist)/sizeof(*filelist); i++)
   {
      kal_uint16 buf[FS_MAX_PATH];
      SDS_ConcatPathAndFileName(buf, dirlist[i], filelist[i]);
      
      memset(SDS_Nvram_TestBuf, i, sizeof(SDS_Nvram_TestBuf));
      
      fd = FS_Open(buf, FS_OPEN_NO_DIR | FS_CREATE_ALWAYS);

      ASSERT(fd >= 0);
      
      if(fd >=0)
      {
         toWrite = filesize[i];
         while(toWrite && fsRet >= 0)
         {
            fsRet = FS_Write(fd, SDS_Nvram_TestBuf, toWrite<sizeof(SDS_Nvram_TestBuf)?toWrite:sizeof(SDS_Nvram_TestBuf), &writtenLen);
            toWrite -= writtenLen;
         }
      }

      FS_Close(fd);
   }

   status = SDS_PackNvramFilesToRecord(TEST_IDX, dirlist, filelist, sizeof(filelist)/sizeof(*filelist));
   ASSERT(status == 0);

   for(i=0; i<sizeof(filelist)/sizeof(*filelist); i++)
   {
      kal_uint16 buf[FS_MAX_PATH];
      SDS_ConcatPathAndFileName(buf, dirlist[i], filelist[i]);
      
      memset(SDS_Nvram_TestBuf, 0, sizeof(SDS_Nvram_TestBuf));

      ASSERT(SDS_GetNvramFileLengthInRecord(TEST_IDX, buf) == filesize[i]);

      status = SDS_ReadNvramFileInRecord(TEST_IDX, buf, SDS_Nvram_TestBuf, sizeof(SDS_Nvram_TestBuf));

      if(status >= 0)
      {
         for(j=0; j<filesize[i]; j++)
         {
            ASSERT(SDS_Nvram_TestBuf[j] == i);
         }
      }
      else if(status == SDS_BUF_TOO_SMALL)
      {
         ASSERT(filesize[i] > sizeof(SDS_Nvram_TestBuf));
      }
      else
      {
         ASSERT(0);
      }
   }

   //Destory the originial file
   for(i=0; i<sizeof(filelist)/sizeof(*filelist); i++)
   {
      kal_uint16 buf[FS_MAX_PATH];
      SDS_ConcatPathAndFileName(buf, dirlist[i], filelist[i]);
      
      memset(SDS_Nvram_TestBuf, 0xcd, sizeof(SDS_Nvram_TestBuf));
      
      fd = FS_Open(buf, FS_OPEN_NO_DIR | FS_CREATE_ALWAYS);

      ASSERT(fd >= 0);
      
      if(fd >=0)
      {
         FS_Write(fd, SDS_Nvram_TestBuf, 16, &writtenLen);
      }

      FS_Close(fd);

      if(i%2)
      {
//         FS_DeletFile?
      }
   }

   status = SDS_RestoreNvramFilesFromRecord(TEST_IDX);
   ASSERT(status >= 0);

   for(i=0; i<sizeof(filelist)/sizeof(*filelist); i++)
   {
      kal_uint16 buf[FS_MAX_PATH];
      SDS_ConcatPathAndFileName(buf, dirlist[i], filelist[i]);
      
      memset(SDS_Nvram_TestBuf, 0xcd, sizeof(SDS_Nvram_TestBuf));
      
      fd = FS_Open(buf, FS_OPEN_NO_DIR);

      ASSERT(fd >= 0);
      
      if(fd >=0)
      {
         FS_Seek(fd, 0, 0);
         
         toRead = filesize[i];
         while(toRead && fsRet >= 0)
         {
            fsRet = FS_Read(fd, SDS_Nvram_TestBuf, MIN(toRead, sizeof(SDS_Nvram_TestBuf)), &readLen);
            toRead -= readLen;

            for(j=0; j<readLen; j++)
            {
               ASSERT(SDS_Nvram_TestBuf[j] == i);
            }
         }
      }

      FS_Close(fd);
   }
   
   return 0;
}
static kal_int32 SDS_NvramPack_WrPreProcess(const kal_uint8 *p_src, kal_uint32 actual_src_len, kal_uint32 src_offset, kal_uint8 *p_dst, kal_uint32 len)
{
    kal_uint32 i, n;

/*
    Packed data structure:
    HEAD_PART>>
       Head structure
       Index * n
    CONTENT_PART
       {
         FileInfoStruct
         Filename m bytes, NULL
         File Content
       } * n
*/    

   PackedDataHeadStruct *pPackedDataHead = NULL;
   PACKED_DATA_INDEX *pIndex = NULL;

   kal_uint32 readLen;

   if(src_offset < sizeof(PackedDataHeadStruct) + sizeof(PACKED_DATA_INDEX)*g_pPackNvramFileStruct->fileCount)
   {
      //Still in head part
      if(src_offset == 0)
      {
         pPackedDataHead = (PackedDataHeadStruct*)p_dst;
         pIndex = (PACKED_DATA_INDEX*)(pPackedDataHead+1);
               
         ASSERT(len > sizeof(PackedDataHeadStruct) /* && (len - sizeof(PackedDataHeadStruct) % sizeof(PACKED_DATA_INDEX)) == 0 Todo */);

         memset(pPackedDataHead, 0x00, sizeof(PackedDataHeadStruct));
         memcpy(pPackedDataHead->head_tag, PACKED_DATA_HEAD_TAG, sizeof(PACKED_DATA_HEAD_TAG));

         pPackedDataHead->fileCount = g_pPackNvramFileStruct->fileCount;
         pPackedDataHead->headDataLen = g_pPackNvramFileStruct->headDataLen;
         pPackedDataHead->fileDataLen = g_pPackNvramFileStruct->fileDataLen;

         n = (len-sizeof(PackedDataHeadStruct))/sizeof(PACKED_DATA_INDEX);
         
         g_pPackNvramFileStruct->currentOffset = g_pPackNvramFileStruct->headDataLen;

      }
      else
      {
         ASSERT(len % sizeof(PACKED_DATA_INDEX) == 0);

         pIndex = (PACKED_DATA_INDEX*)p_dst;
         n = len/sizeof(PACKED_DATA_INDEX);
      }

      for(i=0; i<n; i++)
      {
         kal_uint32 fnLen = SDS_ConcatPathAndFileName(g_pPackNvramFileStruct->fileNameBuf, 
            g_pPackNvramFileStruct->pDirList[g_pPackNvramFileStruct->currentFile], 
            g_pPackNvramFileStruct->pFileList[g_pPackNvramFileStruct->currentFile]);
         
         kal_int32 fileLen = SDS_GetFileSize(g_pPackNvramFileStruct->fileNameBuf);

         if(fileLen < 0)
         {
            goto _fsError;
         }
         
         pIndex->checksum = SDS_CalcFilenameHash(g_pPackNvramFileStruct->fileNameBuf, fnLen);
         pIndex->offset   = g_pPackNvramFileStruct->currentOffset;

         g_pPackNvramFileStruct->currentOffset += (((sizeof(FileInfoStruct) + (fnLen+1)*2 + fileLen)+3)>>2)<<2;
         g_pPackNvramFileStruct->currentFile++;

         pIndex++;

         if(g_pPackNvramFileStruct->currentFile == g_pPackNvramFileStruct->fileCount)
         {
            break;
         }
      }

      if(g_pPackNvramFileStruct->currentFile == g_pPackNvramFileStruct->fileCount)
      {
         //All files are indexed, switch to body part
         //Reset to process the file contents
         g_pPackNvramFileStruct->currentFile = 0;
      }
      len -= ((kal_uint8*)pIndex - p_dst);
      p_dst = (kal_uint8*)pIndex;
   }

   while(len)
   {
      kal_uint8 *pSrc = NULL;
      kal_uint32 copyLen = 0;
      kal_bool stageDone = KAL_FALSE;
      kal_uint32 dummy = 0xcdcdcdcd;

      switch(g_pPackNvramFileStruct->state)
      {
         case SDS_PACK_STATE_DUMP_INFO:
         {
            SDS_ConcatPathAndFileName(g_pPackNvramFileStruct->fileNameBuf, 
               g_pPackNvramFileStruct->pDirList[g_pPackNvramFileStruct->currentFile], 
               g_pPackNvramFileStruct->pFileList[g_pPackNvramFileStruct->currentFile]);
            
            pSrc = (kal_uint8*)(&g_pPackNvramFileStruct->currentFileInfo) + g_pPackNvramFileStruct->offset;
            copyLen = sizeof(g_pPackNvramFileStruct->currentFileInfo) - g_pPackNvramFileStruct->offset;

            if(g_pPackNvramFileStruct->offset == 0)
            {
               kal_int32 fileLen = SDS_GetFileSize(g_pPackNvramFileStruct->fileNameBuf);
               
               if(fileLen < 0)
               {
                  goto _fsError;
               }
               
               g_pPackNvramFileStruct->currentFileInfo.contentLen = fileLen;
               g_pPackNvramFileStruct->currentFileInfo.fnLen = (SDS_CalcFilenameLen(g_pPackNvramFileStruct->fileNameBuf)+1)*2;
            }

         }
         break;

         case SDS_PACK_STATE_DUMP_NAME:
         {
            pSrc = (kal_uint8*)(g_pPackNvramFileStruct->fileNameBuf) + g_pPackNvramFileStruct->offset;
            copyLen = g_pPackNvramFileStruct->currentFileInfo.fnLen - g_pPackNvramFileStruct->offset;
            
         }
         break;

         case SDS_PACK_STATE_DUMP_CONTENT:
         {
            pSrc = NULL;
            copyLen = g_pPackNvramFileStruct->currentFileInfo.contentLen - g_pPackNvramFileStruct->offset;
         }
         break;

         case SDS_PACK_STATE_DUMP_DUMMY_BYTE:
         {
            pSrc = (kal_uint8*)&dummy;
            copyLen = (4-(g_pPackNvramFileStruct->currentFileInfo.fnLen + g_pPackNvramFileStruct->currentFileInfo.contentLen) % 4) % 4;
         }
      }

      if(copyLen > len)
      {
         copyLen = len;
      }
      else
      {
         stageDone = KAL_TRUE;
      }

      if(g_pPackNvramFileStruct->state != SDS_PACK_STATE_DUMP_CONTENT)
      {
         memcpy(p_dst, pSrc, copyLen);
      }
      else
      {
         kal_int32 fsRet;
         kal_int32 fd = -1;
         
         fd = FS_Open(g_pPackNvramFileStruct->fileNameBuf, FS_OPEN_NO_DIR | FS_READ_ONLY);

         if(fd >= 0)
         {
            fsRet = FS_Seek(fd, g_pPackNvramFileStruct->offset, FS_FILE_BEGIN);
            if(fsRet >= 0)
            {
               fsRet = FS_Read(fd, p_dst, copyLen, &readLen);
            }
            FS_Close(fd);
         }

         if(fd < 0 || fsRet < 0 || copyLen != readLen)
         {
            goto _fsError;
         }
      }

      g_pPackNvramFileStruct->offset += copyLen;
      len -= copyLen;
      p_dst += copyLen;

      if(stageDone)
      {
         
         if(g_pPackNvramFileStruct->state == SDS_PACK_STATE_LAST)
         {
            g_pPackNvramFileStruct->state = 0;
            g_pPackNvramFileStruct->currentFile++;
         }
         else
         {
            g_pPackNvramFileStruct->state++;
         }
         g_pPackNvramFileStruct->offset = 0;
      }

   }

   return len;
   
_fsError:
   return SDS_READ_FS_ERROR;
}
Beispiel #10
0
/*
==================
SV_RehashBans_f

Load saved bans from file.
==================
*/
static void SV_RehashBans_f(void)
{
	int index, filelen;
	fileHandle_t readfrom;
	char *textbuf, *curpos, *maskpos, *newlinepos, *endpos;
	char filepath[MAX_QPATH];
	
	// make sure server is running
	if ( !com_sv_running->integer ) {
		return;
	}
	
	serverBansCount = 0;
	
	if(!sv_banFile->string || !*sv_banFile->string)
		return;

	Com_sprintf(filepath, sizeof(filepath), "%s/%s", FS_GetCurrentGameDir(), sv_banFile->string);

	if((filelen = FS_SV_FOpenFileRead(filepath, &readfrom)) >= 0)
	{
		if(filelen < 2)
		{
			// Don't bother if file is too short.
			FS_FCloseFile(readfrom);
			return;
		}

		curpos = textbuf = Z_Malloc(filelen);
		
		filelen = FS_Read(textbuf, filelen, readfrom);
		FS_FCloseFile(readfrom);
		
		endpos = textbuf + filelen;
		
		for(index = 0; index < SERVER_MAXBANS && curpos + 2 < endpos; index++)
		{
			// find the end of the address string
			for(maskpos = curpos + 2; maskpos < endpos && *maskpos != ' '; maskpos++);
			
			if(maskpos + 1 >= endpos)
				break;

			*maskpos = '\0';
			maskpos++;
			
			// find the end of the subnet specifier
			for(newlinepos = maskpos; newlinepos < endpos && *newlinepos != '\n'; newlinepos++);
			
			if(newlinepos >= endpos)
				break;
			
			*newlinepos = '\0';
			
			if(NET_StringToAdr(curpos + 2, &serverBans[index].ip, NA_UNSPEC))
			{
				serverBans[index].isexception = (curpos[0] != '0');
				serverBans[index].subnet = atoi(maskpos);
				
				if(serverBans[index].ip.type == NA_IP &&
				   (serverBans[index].subnet < 1 || serverBans[index].subnet > 32))
				{
					serverBans[index].subnet = 32;
				}
				else if(serverBans[index].ip.type == NA_IP6 &&
					(serverBans[index].subnet < 1 || serverBans[index].subnet > 128))
				{
					serverBans[index].subnet = 128;
				}
			}
			
			curpos = newlinepos + 1;
		}
			
		serverBansCount = index;
		
		Z_Free(textbuf);
	}
}
Beispiel #11
0
int main(void)
	{
	//*******************************************************************
	Init();
	TMRInit(2);		// Initialize Timer interface with Priority=2
	BLIInit();		// Initialize Signal interface
	//*******************************************************************
	//_T1IE 	= 0; 	// Temporarily disable Timer1 interrupt
	//*******************************************************************
	LogInit();			// Initialize Data Logger
	//*******************************************************************
	uint	i;
	char		RData[30];
	char		CData[30];

	for (i = 0; i < 30; i++)
		{
		RData[i] = CData[i] = 0;
		}

	char*		pFN		= "log1.txt";
	void*		pWData	= &"01 02 03 04 05 06 07 08 09";
	//-------------------------------------------------------------------
	
	CETYPE			RC;
	uint			ReadCnt;
	
	FSFILE			File;
	SEARCH_STATE	Search;
	//*******************************************************************
	BLISignalON();
	//*******************************************************************
	
	// Search for every entry in the Root
	RC = FS_FindFirst(	"*", ATTR_NONE,  ATTR_NONE, &Search, &File);	
	while (CE_GOOD == RC)
		{
		RC = FS_FindNext(&Search, &File);
		}

	// Search only for files
	RC = FS_FindFirst(	"*", ATTR_NONE,  ATTR_DIRECTORY, &Search, &File);	
	while (CE_GOOD == RC)
		{
		RC = FS_FindNext(&Search, &File);
		}

	// Search only for directories
Deeper:
	RC = FS_FindFirst(	"*", ATTR_DIRECTORY,  ATTR_NONE, &Search, &File);	
	if (CE_GOOD == RC)
		{
		RC = FS_chDir(&File);
		if (CE_GOOD == RC)
			goto Deeper;
		}
		
Higher:
	RC = FS_GetCWD(&File);
	RC = CE_GOOD;
	RC = FS_chDirUp();
	if (CE_GOOD == RC)
		goto Higher;
		
	//*******************************************************************


	//------------------------------
	// Create (Open) file for Writing and Reading 
	//------------------------------
	RC = FS_CreateFile(pFN, FS_CREATE_NEW, &File);
	while ( RC != CE_GOOD );
	//------------------------------
	// Write sample string to file
	//------------------------------
   	RC = FS_Write (&File, pWData, 26 );
	while (CE_GOOD != RC);
	//------------------------------
	// Check position in the file
	//------------------------------
   	i = FS_GetPosition (&File);
	while (i != 26);
	//------------------------------
	// Seek to start
	//------------------------------
   	FS_SeekStart(&File);
	//------------------------------
	// Reed from start
	//------------------------------
   	RC = FS_Read (&File, RData, 26, &ReadCnt);
	while (CE_GOOD != RC);
	//------------------------------
	// Close the file - save changes
	//------------------------------
	RC = FS_Flush(&File);
   	while ( RC != CE_GOOD );
	//------------------------------

	//------------------------------
	// Open file for Reading 
	//------------------------------
	RC = FS_CreateFile(pFN, FS_READ_ONLY, &File);
	while ( RC != CE_GOOD );
	//------------------------------
	// Reed from start
	//------------------------------
   	RC = FS_Read (&File, CData, 26, &ReadCnt);
	while (CE_GOOD != RC);
	//------------------------------
	// Close the file - save changes
	//------------------------------
	RC = FS_Flush(&File);
   	while ( RC != CE_GOOD );
	//------------------------------
	i = 1 + i;

	//*******************************************************************
	BLISignalOFF();
	//------------------------------
	while(1);
	return 0;
	}
Beispiel #12
0
/*
====================
CL_CgameSystemCalls

The cgame module is making a system call
====================
*/
intptr_t CL_CgameSystemCalls( intptr_t *args )
{
	if( cls.cgInterface == 2 && args[0] >= CG_R_SETCLIPREGION && args[0] < CG_MEMSET )
    {
		if( args[0] < CG_S_STOPBACKGROUNDTRACK - 1 )
			args[0] += 1;

        else if( args[0] < CG_S_STOPBACKGROUNDTRACK + 4 )
			args[0] += CG_PARSE_ADD_GLOBAL_DEFINE - CG_S_STOPBACKGROUNDTRACK + 1;

        else if( args[0] < CG_PARSE_ADD_GLOBAL_DEFINE + 4 )
			args[0] -= 4;

        else if( args[0] >= CG_PARSE_SOURCE_FILE_AND_LINE && args[0] <= CG_S_SOUNDDURATION )
			args[0] = CG_PARSE_SOURCE_FILE_AND_LINE - 1337 - args[0] ;
	}

	switch( args[0] )
    {
        case CG_PRINT:
            Com_Printf( "%s", (const char*)VMA(1) );
            return 0;
        case CG_ERROR:
            if( probingCG )
            {
                cls.cgInterface = 2; // this is a 1.1.0 cgame
                return 0;
            }
            Com_Error( ERR_DROP, "%s", (const char*)VMA(1) );
            return 0;
        case CG_MILLISECONDS:
            return Sys_Milliseconds();
        case CG_CVAR_REGISTER:
            Cvar_Register( (vmCvar_t*)VMA(1), (const char*)VMA(2), (const char*)VMA(3), args[4] ); 
            return 0;
        case CG_CVAR_UPDATE:
            Cvar_Update( (vmCvar_t*)VMA(1) );
            return 0;
        case CG_CVAR_SET:
            Cvar_SetSafe( (const char*)VMA(1), (const char*)VMA(2) );
            return 0;
        case CG_CVAR_VARIABLESTRINGBUFFER:
            Cvar_VariableStringBuffer( (const char*)VMA(1), (char*)VMA(2), args[3] );
            return 0;
        case CG_ARGC:
            return Cmd_Argc();
        case CG_ARGV:
            Cmd_ArgvBuffer( args[1], (char*)VMA(2), args[3] );
            return 0;
        case CG_ARGS:
            Cmd_ArgsBuffer( (char*)VMA(1), args[2] );
            return 0;
        case CG_LITERAL_ARGS:
            Cmd_LiteralArgsBuffer( (char*)VMA(1), args[2] );
            return 0;
        case CG_FS_FOPENFILE:
            return FS_FOpenFileByMode( (const char*)VMA(1), (fileHandle_t*)VMA(2), (FS_Mode)args[3] );
        case CG_FS_READ:
            FS_Read( VMA(1), args[2], args[3] );
            return 0;
        case CG_FS_WRITE:
            FS_Write( VMA(1), args[2], args[3] );
            return 0;
        case CG_FS_FCLOSEFILE:
            FS_FCloseFile( args[1] );
            return 0;
        case CG_FS_SEEK:
            return FS_Seek( (fileHandle_t)args[1], args[2], (FS_Origin)args[3] );
        case CG_FS_GETFILELIST:
            return FS_GetFileList( (const char*)VMA(1), (const char*)VMA(2), (char*)VMA(3), args[4] );
        case CG_SENDCONSOLECOMMAND:
            Cbuf_AddText( (const char*)VMA(1) );
            return 0;
        case CG_ADDCOMMAND:
            CL_AddCgameCommand( (const char*)VMA(1) );
            return 0;
        case CG_REMOVECOMMAND:
            Cmd_RemoveCommandSafe( (const char*)VMA(1) );
            return 0;
        case CG_SENDCLIENTCOMMAND:
            CL_AddReliableCommand((const char*)VMA(1), false);
            return 0;
        case CG_UPDATESCREEN:
            // this is used during lengthy level loading, so pump message loop
            //		Com_EventLoop();	// FIXME: if a server restarts here, BAD THINGS HAPPEN!
            // We can't call Com_EventLoop here, a restart will crash and this _does_ happen
            // if there is a map change while we are downloading at pk3.
            // ZOID
            SCR_UpdateScreen();
            return 0;
        case CG_CM_LOADMAP:
            CL_CM_LoadMap( (const char*)VMA(1) );
            return 0;
        case CG_CM_NUMINLINEMODELS:
            return CM_NumInlineModels();
        case CG_CM_INLINEMODEL:
            return CM_InlineModel( args[1] );
        case CG_CM_TEMPBOXMODEL:
            return CM_TempBoxModel( (const float*)VMA(1), (const float*)VMA(2), false );
        case CG_CM_TEMPCAPSULEMODEL:
            return CM_TempBoxModel( (const float*)VMA(1), (const float*)VMA(2), true );
        case CG_CM_POINTCONTENTS:
            return CM_PointContents( (const float*)VMA(1), args[2] );
        case CG_CM_TRANSFORMEDPOINTCONTENTS:
            return CM_TransformedPointContents( (const float*)VMA(1), (clipHandle_t)args[2],
                                                (const float*)VMA(3), (const float*)VMA(4) );
        case CG_CM_BOXTRACE:
            CM_BoxTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3),
                         (float*)VMA(4), (float*)VMA(5), (clipHandle_t)args[6], args[7], TT_AABB );
            return 0;
        case CG_CM_CAPSULETRACE:
            CM_BoxTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3),
                         (float*)VMA(4), (float*)VMA(5), (clipHandle_t)args[6], args[7], TT_CAPSULE );
            return 0;
        case CG_CM_TRANSFORMEDBOXTRACE:
            CM_TransformedBoxTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3),
                                    (float*)VMA(4), (float*)VMA(5), (clipHandle_t)args[6], args[7],
                                    (const float*)VMA(8), (const float*)VMA(9), TT_AABB );
            return 0;
        case CG_CM_TRANSFORMEDCAPSULETRACE:
            CM_TransformedBoxTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3),
                                    (float*)VMA(4), (float*)VMA(5), (clipHandle_t)args[6], args[7],
                                    (const float*)VMA(8), (const float*)VMA(9), TT_CAPSULE );
            return 0;
        case CG_CM_BISPHERETRACE:
            CM_BiSphereTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3), VMF(4), VMF(5), (clipHandle_t)args[6], args[7] );
            return 0;
        case CG_CM_TRANSFORMEDBISPHERETRACE:
            CM_TransformedBiSphereTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3),
                                         VMF(4), VMF(5), (clipHandle_t)args[6], args[7], (const float*)VMA(8) );
            return 0;
        case CG_CM_MARKFRAGMENTS:
            {
            float (&arg2)[3][3] = *reinterpret_cast<float (*)[3][3]>(VMA(2));
            return re.MarkFragments( args[1], arg2, (const float*)VMA(3), args[4], (float*)VMA(5), args[6], (markFragment_t*)VMA(7) );
            }
        case CG_S_STARTSOUND:
            S_StartSound( (float*)VMA(1), args[2], args[3], (sfxHandle_t)args[4] );
            return 0;
        case CG_S_STARTLOCALSOUND:
            S_StartLocalSound( (sfxHandle_t)args[1], args[2] );
            return 0;
        case CG_S_CLEARLOOPINGSOUNDS:
            S_ClearLoopingSounds( (bool)args[1] );
            return 0;
        case CG_S_ADDLOOPINGSOUND:
            S_AddLoopingSound( args[1], (const float*)VMA(2), (const float*)VMA(3), (sfxHandle_t)args[4] );
            return 0;
        case CG_S_ADDREALLOOPINGSOUND:
            S_AddRealLoopingSound( args[1], (const float*)VMA(2), (const float*)VMA(3), (sfxHandle_t)args[4] );
            return 0;
        case CG_S_STOPLOOPINGSOUND:
            S_StopLoopingSound( args[1] );
            return 0;
        case CG_S_UPDATEENTITYPOSITION:
            S_UpdateEntityPosition( args[1], (const float*)VMA(2) );
            return 0;
        case CG_S_RESPATIALIZE:
            {
            float (&arg3)[3][3] = *reinterpret_cast<float (*)[3][3]>(VMA(3));
            S_Respatialize( args[1], (const float*)VMA(2), arg3, args[4] );
            return 0;
            }
        case CG_S_REGISTERSOUND:
            return S_RegisterSound( (const char*)VMA(1), (bool)args[2] );
        case CG_S_SOUNDDURATION:
            return S_SoundDuration( args[1] );
        case CG_S_STARTBACKGROUNDTRACK:
            S_StartBackgroundTrack( (const char*)VMA(1), (const char*)VMA(2) );
            return 0;
        case CG_R_LOADWORLDMAP:
            re.LoadWorld( (const char*)VMA(1) );
            return 0; 
        case CG_R_REGISTERMODEL:
            return re.RegisterModel( (const char*)VMA(1) );
        case CG_R_REGISTERSKIN:
            return re.RegisterSkin( (const char*)VMA(1) );
        case CG_R_REGISTERSHADER:
            return re.RegisterShader( (const char*)VMA(1) );
        case CG_R_REGISTERSHADERNOMIP:
            return re.RegisterShaderNoMip( (const char*)VMA(1) );
        case CG_R_REGISTERFONT:
            re.RegisterFont( (const char*)VMA(1), args[2], (fontInfo_t*)VMA(3));
            return 0;
        case CG_R_CLEARSCENE:
            re.ClearScene();
            return 0;
        case CG_R_ADDREFENTITYTOSCENE:
            re.AddRefEntityToScene( (const refEntity_t*)VMA(1) );
            return 0;
        case CG_R_ADDPOLYTOSCENE:
            re.AddPolyToScene( (qhandle_t)args[1], args[2], (const polyVert_t*)VMA(3), 1 );
            return 0;
        case CG_R_ADDPOLYSTOSCENE:
            re.AddPolyToScene( (qhandle_t)args[1], args[2], (const polyVert_t*)VMA(3), args[4] );
            return 0;
        case CG_R_LIGHTFORPOINT:
            return re.LightForPoint( (float*)VMA(1), (float*)VMA(2), (float*)VMA(3), (float*)VMA(4) );
        case CG_R_ADDLIGHTTOSCENE:
            re.AddLightToScene( (const float*)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
            return 0;
        case CG_R_ADDADDITIVELIGHTTOSCENE:
            re.AddAdditiveLightToScene( (const float*)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
            return 0;
        case CG_R_RENDERSCENE:
            re.RenderScene( (const refdef_t*)VMA(1) );
            return 0;
        case CG_R_SETCOLOR:
            re.SetColor( (const float*)VMA(1) );
            return 0;
        case CG_R_SETCLIPREGION:
            re.SetClipRegion( (const float*)VMA(1) );
            return 0;
        case CG_R_DRAWSTRETCHPIC:
            re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), (qhandle_t)args[9] );
            return 0;
        case CG_R_MODELBOUNDS:
            re.ModelBounds( (qhandle_t)args[1], (float*)VMA(2), (float*)VMA(3) );
            return 0;
        case CG_R_LERPTAG:
            return re.LerpTag( (orientation_t*)VMA(1), args[2], args[3], args[4], VMF(5), (const char*)VMA(6) );
        case CG_GETGLCONFIG:
            CL_GetGlconfig( (glconfig_t*)VMA(1) );
            return 0;
        case CG_GETGAMESTATE:
            CL_GetGameState( (gameState_t*)VMA(1) );
            return 0;
        case CG_GETCURRENTSNAPSHOTNUMBER:
            CL_GetCurrentSnapshotNumber( (int*)VMA(1), (int*)VMA(2) );
            return 0;
        case CG_GETSNAPSHOT:
            return CL_GetSnapshot( args[1], (snapshot_t*)VMA(2) );
        case CG_GETSERVERCOMMAND:
            return CL_GetServerCommand( args[1] );
        case CG_GETCURRENTCMDNUMBER:
            return CL_GetCurrentCmdNumber();
        case CG_GETUSERCMD:
            return CL_GetUserCmd( args[1], (usercmd_t*)VMA(2) );
        case CG_SETUSERCMDVALUE:
            CL_SetUserCmdValue( args[1], VMF(2) );
            return 0;
        case CG_MEMORY_REMAINING:
            return Hunk_MemoryRemaining();
        case CG_KEY_ISDOWN:
            return Key_IsDown( args[1] );
        case CG_KEY_GETCATCHER:
            return Key_GetCatcher();
        case CG_KEY_SETCATCHER:
            // don't allow the cgame module to toggle the console
            Key_SetCatcher( ( args[1] & ~KEYCATCH_CONSOLE ) | ( Key_GetCatcher() & KEYCATCH_CONSOLE ) );
            return 0;
        case CG_KEY_GETKEY:
            return Key_GetKey( (const char*)VMA(1) );

        case CG_GETDEMOSTATE:
            return CL_DemoState( );
        case CG_GETDEMOPOS:
            return CL_DemoPos( );
        case CG_GETDEMONAME:
            CL_DemoName( (char*)VMA(1), args[2] );
            return 0;

        case CG_KEY_KEYNUMTOSTRINGBUF:
            Key_KeynumToStringBuf( args[1], (char*)VMA(2), args[3] );
            return 0;
        case CG_KEY_GETBINDINGBUF:
            Key_GetBindingBuf( args[1], (char*)VMA(2), args[3] );
            return 0;
        case CG_KEY_SETBINDING:
            Key_SetBinding( args[1], (const char*)VMA(2) );
            return 0;

        case CG_PARSE_ADD_GLOBAL_DEFINE:
            return Parse_AddGlobalDefine( (char*)VMA(1) );
        case CG_PARSE_LOAD_SOURCE:
            return Parse_LoadSourceHandle( (const char*)VMA(1) );
        case CG_PARSE_FREE_SOURCE:
            return Parse_FreeSourceHandle( args[1] );
        case CG_PARSE_READ_TOKEN:
            return Parse_ReadTokenHandle( args[1], (pc_token_t*)VMA(2) );
        case CG_PARSE_SOURCE_FILE_AND_LINE:
            return Parse_SourceFileAndLine( args[1], (char*)VMA(2), (int*)VMA(3) );

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

        case CG_KEY_GETOVERSTRIKEMODE:
            return Key_GetOverstrikeMode( );

        case CG_FIELD_COMPLETELIST:
            Field_CompleteList( (char*)VMA(1) );
            return 0;

        case CG_MEMSET:
            ::memset( VMA(1), args[2], args[3] );
            return 0;
        case CG_MEMCPY:
            ::memcpy( VMA(1), VMA(2), args[3] );
            return 0;
        case CG_STRNCPY:
            safe_strncpy( (char*)VMA(1), (const char*)VMA(2), args[3] );
            return args[1];
        case CG_SIN:
            return FloatAsInt( sin( VMF(1) ) );
        case CG_COS:
            return FloatAsInt( cos( VMF(1) ) );
        case CG_ATAN2:
            return FloatAsInt( atan2( VMF(1), VMF(2) ) );
        case CG_SQRT:
            return FloatAsInt( sqrt( VMF(1) ) );
        case CG_FLOOR:
            return FloatAsInt( floor( VMF(1) ) );
        case CG_CEIL:
            return FloatAsInt( ceil( VMF(1) ) );
        case CG_ACOS:
            return FloatAsInt( Q_acos( VMF(1) ) );

        case CG_S_STOPBACKGROUNDTRACK:
            S_StopBackgroundTrack();
            return 0;

        case CG_REAL_TIME:
            return Com_RealTime( (qtime_t*)VMA(1) );
        case CG_SNAPVECTOR:
            Q_SnapVector((float*)VMA(1));
            return 0;

        case CG_CIN_PLAYCINEMATIC:
            return CIN_PlayCinematic((const char*)VMA(1), args[2], args[3], args[4], args[5], args[6]);

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

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

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

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

        case CG_R_REMAP_SHADER:
            re.RemapShader( (const char*)VMA(1), (const char*)VMA(2), (const char*)VMA(3) );
            return 0;

        case CG_GET_ENTITY_TOKEN:
            return re.GetEntityToken( (char*)VMA(1), args[2] );
        case CG_R_INPVS:
            return re.inPVS( (const float*)VMA(1), (const float*)VMA(2) );

        default:
            assert(0);
            Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] );
    }
	return 0;
}
Beispiel #13
0
intptr_t CL_UISystemCalls( intptr_t *args ) {
	switch ( args[0] ) {
		//rww - alright, DO NOT EVER add a GAME/CGAME/UI generic call without adding a trap to match, and
		//all of these traps must be shared and have cases in sv_game, cl_cgame, and cl_ui. They must also
		//all be in the same order, and start at 100.
	case TRAP_MEMSET:
		Com_Memset( VMA(1), args[2], args[3] );
		return 0;

	case TRAP_MEMCPY:
		Com_Memcpy( VMA(1), VMA(2), args[3] );
		return 0;

	case TRAP_STRNCPY:
		strncpy( (char *)VMA(1), (const char *)VMA(2), args[3] );
		return args[1];

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

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

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

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

	case TRAP_MATRIXMULTIPLY:
		MatrixMultiply( (vec3_t *)VMA(1), (vec3_t *)VMA(2), (vec3_t *)VMA(3) );
		return 0;

	case TRAP_ANGLEVECTORS:
		AngleVectors( (const float *)VMA(1), (float *)VMA(2), (float *)VMA(3), (float *)VMA(4) );
		return 0;

	case TRAP_PERPENDICULARVECTOR:
		PerpendicularVector( (float *)VMA(1), (const float *)VMA(2) );
		return 0;

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

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

	case TRAP_TESTPRINTINT:
		return 0;

	case TRAP_TESTPRINTFLOAT:
		return 0;

	case TRAP_ACOS:
		return FloatAsInt( Q_acos( VMF(1) ) );

	case TRAP_ASIN:
		return FloatAsInt( Q_asin( VMF(1) ) );

	case UI_ERROR:
		Com_Error( ERR_DROP, "%s", VMA(1) );
		return 0;

	case UI_PRINT:
		Com_Printf( "%s", VMA(1) );
		return 0;

	case UI_MILLISECONDS:
		return Sys_Milliseconds();

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

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

	case UI_CVAR_SET:
		Cvar_VM_Set( (const char *)VMA(1), (const char *)VMA(2), VM_UI );
		return 0;

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

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

	case UI_CVAR_SETVALUE:
		Cvar_VM_SetValue( (const char *)VMA(1), VMF(2), VM_UI );
		return 0;

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

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

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

	case UI_ARGC:
		return Cmd_Argc();

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

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

	case UI_FS_FOPENFILE:
		return FS_FOpenFileByMode( (const char *)VMA(1), (int *)VMA(2), (fsMode_t)args[3] );

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

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

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

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

	case UI_R_REGISTERMODEL:
		return re->RegisterModel( (const char *)VMA(1) );

	case UI_R_REGISTERSKIN:
		return re->RegisterSkin( (const char *)VMA(1) );

	case UI_R_REGISTERSHADERNOMIP:
		return re->RegisterShaderNoMip( (const char *)VMA(1) );

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

	case UI_R_CLEARSCENE:
		re->ClearScene();
		return 0;

	case UI_R_ADDREFENTITYTOSCENE:
		re->AddRefEntityToScene( (const refEntity_t *)VMA(1) );
		return 0;

	case UI_R_ADDPOLYTOSCENE:
		re->AddPolyToScene( args[1], args[2], (const polyVert_t *)VMA(3), 1 );
		return 0;

	case UI_R_ADDLIGHTTOSCENE:
		re->AddLightToScene( (const float *)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
		return 0;

	case UI_R_RENDERSCENE:
		re->RenderScene( (const refdef_t *)VMA(1) );
		return 0;

	case UI_R_SETCOLOR:
		re->SetColor( (const float *)VMA(1) );
		return 0;

	case UI_R_DRAWSTRETCHPIC:
		re->DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9] );
		return 0;

	case UI_R_MODELBOUNDS:
		re->ModelBounds( args[1], (float *)VMA(2), (float *)VMA(3) );
		return 0;

	case UI_UPDATESCREEN:
		SCR_UpdateScreen();
		return 0;

	case UI_CM_LERPTAG:
		re->LerpTag( (orientation_t *)VMA(1), args[2], args[3], args[4], VMF(5), (const char *)VMA(6) );
		return 0;

	case UI_S_REGISTERSOUND:
		return S_RegisterSound( (const char *)VMA(1) );

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

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

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

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

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

	case UI_KEY_GETOVERSTRIKEMODE:
		return Key_GetOverstrikeMode();

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

	case UI_KEY_CLEARSTATES:
		Key_ClearStates();
		return 0;

	case UI_KEY_GETCATCHER:
		return Key_GetCatcher();

	case UI_KEY_SETCATCHER:
		CL_Key_SetCatcher( args[1] );
		return 0;

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

	case UI_GETCLIENTSTATE:
		CL_GetClientState( (uiClientState_t *)VMA(1) );
		return 0;		

	case UI_GETGLCONFIG:
		CL_GetGlconfig( (glconfig_t *)VMA(1) );
		return 0;

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

	case UI_LAN_LOADCACHEDSERVERS:
		LAN_LoadCachedServers();
		return 0;

	case UI_LAN_SAVECACHEDSERVERS:
		LAN_SaveServersToCache();
		return 0;

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

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

	case UI_LAN_GETPINGQUEUECOUNT:
		return LAN_GetPingQueueCount();

	case UI_LAN_CLEARPING:
		LAN_ClearPing( args[1] );
		return 0;

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

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

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

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

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

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

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

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

	case UI_LAN_UPDATEVISIBLEPINGS:
		return LAN_UpdateVisiblePings( args[1] );

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

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

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

	case UI_MEMORY_REMAINING:
		return Hunk_MemoryRemaining();

	case UI_R_REGISTERFONT:
		return re->RegisterFont( (const char *)VMA(1) );

	case UI_R_FONT_STRLENPIXELS:
		return re->Font_StrLenPixels( (const char *)VMA(1), args[2], VMF(3) );

	case UI_R_FONT_STRLENCHARS:
		return re->Font_StrLenChars( (const char *)VMA(1) );

	case UI_R_FONT_STRHEIGHTPIXELS:
		return re->Font_HeightPixels( args[1], VMF(2) );

	case UI_R_FONT_DRAWSTRING:
		re->Font_DrawString( args[1], args[2], (const char *)VMA(3), (const float *) VMA(4), args[5], args[6], VMF(7) );
		return 0;

	case UI_LANGUAGE_ISASIAN:
		return re->Language_IsAsian();

	case UI_LANGUAGE_USESSPACES:
		return re->Language_UsesSpaces();

	case UI_ANYLANGUAGE_READCHARFROMSTRING:
		return re->AnyLanguage_ReadCharFromString( (const char *)VMA(1), (int *) VMA(2), (qboolean *) VMA(3) );

	case UI_PC_ADD_GLOBAL_DEFINE:
		return botlib_export->PC_AddGlobalDefine( (char *)VMA(1) );

	case UI_PC_LOAD_SOURCE:
		return botlib_export->PC_LoadSourceHandle( (const char *)VMA(1) );

	case UI_PC_FREE_SOURCE:
		return botlib_export->PC_FreeSourceHandle( args[1] );

	case UI_PC_READ_TOKEN:
		return botlib_export->PC_ReadTokenHandle( args[1], (struct pc_token_s *)VMA(2) );

	case UI_PC_SOURCE_FILE_AND_LINE:
		return botlib_export->PC_SourceFileAndLine( args[1], (char *)VMA(2), (int *)VMA(3) );

	case UI_PC_LOAD_GLOBAL_DEFINES:
		return botlib_export->PC_LoadGlobalDefines ( (char *)VMA(1) );

	case UI_PC_REMOVE_ALL_GLOBAL_DEFINES:
		botlib_export->PC_RemoveAllGlobalDefines ( );
		return 0;

	case UI_S_STOPBACKGROUNDTRACK:
		S_StopBackgroundTrack();
		return 0;

	case UI_S_STARTBACKGROUNDTRACK:
		S_StartBackgroundTrack( (const char *)VMA(1), (const char *)VMA(2), qfalse );
		return 0;

	case UI_REAL_TIME:
		return Com_RealTime( (struct qtime_s *)VMA(1) );

	case UI_CIN_PLAYCINEMATIC:
		Com_DPrintf("UI_CIN_PlayCinematic\n");
		return CIN_PlayCinematic((const char *)VMA(1), args[2], args[3], args[4], args[5], args[6]);

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

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

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

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

	case UI_R_REMAP_SHADER:
		re->RemapShader( (const char *)VMA(1), (const char *)VMA(2), (const char *)VMA(3) );
		return 0;

	case UI_SP_GETNUMLANGUAGES:
		return SE_GetNumLanguages();

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

	case UI_SP_GETSTRINGTEXTSTRING:
		return CL_SE_GetStringTextString( (const char *)VMA(1), (char *)VMA(2), args[3] );

	case UI_G2_LISTSURFACES:
		re->G2API_ListSurfaces( (CGhoul2Info *) args[1] );
		return 0;

	case UI_G2_LISTBONES:
		re->G2API_ListBones( (CGhoul2Info *) args[1], args[2]);
		return 0;

	case UI_G2_HAVEWEGHOULMODELS:
		return re->G2API_HaveWeGhoul2Models( *((CGhoul2Info_v *)args[1]) );

	case UI_G2_SETMODELS:
		re->G2API_SetGhoul2ModelIndexes( *((CGhoul2Info_v *)args[1]),(qhandle_t *)VMA(2),(qhandle_t *)VMA(3));
		return 0;

	case UI_G2_GETBOLT:
		return re->G2API_GetBoltMatrix(*((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));

	case UI_G2_GETBOLT_NOREC:
		re->G2API_BoltMatrixReconstruction( qfalse );//gG2_GBMNoReconstruct = qtrue;
		return re->G2API_GetBoltMatrix(*((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));

	case UI_G2_GETBOLT_NOREC_NOROT:
		// cgame reconstructs bolt matrix, why is this different?
		re->G2API_BoltMatrixReconstruction( qfalse );//gG2_GBMNoReconstruct = qtrue;
		re->G2API_BoltMatrixSPMethod( qtrue );//gG2_GBMUseSPMethod = qtrue;
		return re->G2API_GetBoltMatrix(*((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));

	case UI_G2_INITGHOUL2MODEL:
#ifdef _FULL_G2_LEAK_CHECKING
		g_G2AllocServer = 0;
#endif
		return	re->G2API_InitGhoul2Model((CGhoul2Info_v **)VMA(1), (const char *)VMA(2), args[3], (qhandle_t) args[4], (qhandle_t) args[5], args[6], args[7]);

	case UI_G2_COLLISIONDETECT:
	case UI_G2_COLLISIONDETECTCACHE:
		return 0; //not supported for ui

	case UI_G2_ANGLEOVERRIDE:
		return re->G2API_SetBoneAngles(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3), (float *)VMA(4), args[5], (const Eorientations) args[6], (const Eorientations) args[7], (const Eorientations) args[8], (qhandle_t *)VMA(9), args[10], args[11] );

	case UI_G2_CLEANMODELS:
#ifdef _FULL_G2_LEAK_CHECKING
		g_G2AllocServer = 0;
#endif
		re->G2API_CleanGhoul2Models((CGhoul2Info_v **)VMA(1));
		//	re->G2API_CleanGhoul2Models((CGhoul2Info_v **)args[1]);
		return 0;

	case UI_G2_PLAYANIM:
		return re->G2API_SetBoneAnim(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3), args[4], args[5], args[6], VMF(7), args[8], VMF(9), args[10]);

	case UI_G2_GETBONEANIM:
		{
			CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]);
			int modelIndex = args[10];

			return re->G2API_GetBoneAnim(&g2[modelIndex], (const char*)VMA(2), args[3], (float *)VMA(4), (int *)VMA(5), (int *)VMA(6), (int *)VMA(7), (float *)VMA(8), (int *)VMA(9));
		}

	case UI_G2_GETBONEFRAME:
		{ //rwwFIXMEFIXME: Just make a G2API_GetBoneFrame func too. This is dirty.
			CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]);
			int modelIndex = args[6];
			int iDontCare1 = 0, iDontCare2 = 0, iDontCare3 = 0;
			float fDontCare1 = 0;

			return re->G2API_GetBoneAnim(&g2[modelIndex], (const char*)VMA(2), args[3], (float *)VMA(4), &iDontCare1, &iDontCare2, &iDontCare3, &fDontCare1, (int *)VMA(5));
		}

	case UI_G2_GETGLANAME:
		//	return (int)G2API_GetGLAName(*((CGhoul2Info_v *)VMA(1)), args[2]);
		{
			char *point = ((char *)VMA(3));
			char *local;
			local = re->G2API_GetGLAName(*((CGhoul2Info_v *)args[1]), args[2]);
			if (local)
			{
				strcpy(point, local);
			}
		}
		return 0;

	case UI_G2_COPYGHOUL2INSTANCE:
		return (int)re->G2API_CopyGhoul2Instance(*((CGhoul2Info_v *)args[1]), *((CGhoul2Info_v *)args[2]), args[3]);

	case UI_G2_COPYSPECIFICGHOUL2MODEL:
		re->G2API_CopySpecificG2Model(*((CGhoul2Info_v *)args[1]), args[2], *((CGhoul2Info_v *)args[3]), args[4]);
		return 0;

	case UI_G2_DUPLICATEGHOUL2INSTANCE:
#ifdef _FULL_G2_LEAK_CHECKING
		g_G2AllocServer = 0;
#endif
		re->G2API_DuplicateGhoul2Instance(*((CGhoul2Info_v *)args[1]), (CGhoul2Info_v **)VMA(2));
		return 0;

	case UI_G2_HASGHOUL2MODELONINDEX:
		return (int)re->G2API_HasGhoul2ModelOnIndex((CGhoul2Info_v **)VMA(1), args[2]);
		//return (int)G2API_HasGhoul2ModelOnIndex((CGhoul2Info_v **)args[1], args[2]);

	case UI_G2_REMOVEGHOUL2MODEL:
#ifdef _FULL_G2_LEAK_CHECKING
		g_G2AllocServer = 0;
#endif
		return (int)re->G2API_RemoveGhoul2Model((CGhoul2Info_v **)VMA(1), args[2]);
		//return (int)G2API_RemoveGhoul2Model((CGhoul2Info_v **)args[1], args[2]);

	case UI_G2_ADDBOLT:
		return re->G2API_AddBolt(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3));

	case UI_G2_SETBOLTON:
		re->G2API_SetBoltInfo(*((CGhoul2Info_v *)args[1]), args[2], args[3]);
		return 0;

	case UI_G2_SETROOTSURFACE:
		return re->G2API_SetRootSurface(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3));

	case UI_G2_SETSURFACEONOFF:
		return re->G2API_SetSurfaceOnOff(*((CGhoul2Info_v *)args[1]), (const char *)VMA(2), /*(const int)VMA(3)*/args[3]);

	case UI_G2_SETNEWORIGIN:
		return re->G2API_SetNewOrigin(*((CGhoul2Info_v *)args[1]), /*(const int)VMA(2)*/args[2]);

	case UI_G2_GETTIME:
		return re->G2API_GetTime(0);

	case UI_G2_SETTIME:
		re->G2API_SetTime(args[1], args[2]);
		return 0;

	case UI_G2_SETRAGDOLL:
		return 0; //not supported for ui
		break;

	case UI_G2_ANIMATEG2MODELS:
		return 0; //not supported for ui
		break;

	case UI_G2_SETBONEIKSTATE:
		return re->G2API_SetBoneIKState(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3), args[4], (sharedSetBoneIKStateParams_t *)VMA(5));

	case UI_G2_IKMOVE:
		return re->G2API_IKMove(*((CGhoul2Info_v *)args[1]), args[2], (sharedIKMoveParams_t *)VMA(3));

	case UI_G2_GETSURFACENAME:
		{ //Since returning a pointer in such a way to a VM seems to cause MASSIVE FAILURE<tm>, we will shove data into the pointer the vm passes instead
			char *point = ((char *)VMA(4));
			char *local;
			int modelindex = args[3];

			CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]);

			local = re->G2API_GetSurfaceName(&g2[modelindex], args[2]);
			if (local)
			{
				strcpy(point, local);
			}
		}

		return 0;
	case UI_G2_SETSKIN:
		{
			CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]);
			int modelIndex = args[2];

			return re->G2API_SetSkin(&g2[modelIndex], args[3], args[4]);
		}

	case UI_G2_ATTACHG2MODEL:
		{
			CGhoul2Info_v *g2From = ((CGhoul2Info_v *)args[1]);
			CGhoul2Info_v *g2To = ((CGhoul2Info_v *)args[3]);

			return re->G2API_AttachG2Model(*g2From, args[2], *g2To, args[4], args[5]);
		}

	default:
		Com_Error( ERR_DROP, "Bad UI system trap: %ld", (long int) args[0] );

	}

	return 0;
}
Beispiel #14
0
void
SCR_PlayCinematic(char *arg)
{
    int width, height;
    byte *palette;
    char name[MAX_OSPATH], *dot;

    /* Make sure that all keys are marked up. Under
       some circumstances cinematics are started with
       at least one key marked down, causing them to
       abort right after the first frame... */
    Key_MarkAllUp();

    /* make sure background music is not playing */
#ifdef CDA
    CDAudio_Stop();
#endif
#ifdef OGG
    OGG_Stop();
#endif

    cl.cinematicframe = 0;
    dot = strstr(arg, ".");

    /* static pcx image */
    if (dot && !strcmp(dot, ".pcx"))
    {
        Com_sprintf(name, sizeof(name), "pics/%s", arg);
        SCR_LoadPCX(name, &cin.pic, &palette, &cin.width, &cin.height);
        cl.cinematicframe = -1;
        cl.cinematictime = 1;
        SCR_EndLoadingPlaque();
        cls.state = ca_active;

        if (!cin.pic)
        {
            Com_Printf("%s not found.\n", name);
            cl.cinematictime = 0;
        }
        else
        {
            memcpy(cl.cinematicpalette, palette, sizeof(cl.cinematicpalette));
            Z_Free(palette);
        }

        return;
    }

    Com_sprintf(name, sizeof(name), "video/%s", arg);
    FS_FOpenFile(name, &cl.cinematic_file, false);

    if (!cl.cinematic_file)
    {
        SCR_FinishCinematic();
        cl.cinematictime = 0; /* done */
        return;
    }

    SCR_EndLoadingPlaque();

    cls.state = ca_active;

    FS_Read(&width, 4, cl.cinematic_file);
    FS_Read(&height, 4, cl.cinematic_file);
    cin.width = LittleLong(width);
    cin.height = LittleLong(height);

    FS_Read(&cin.s_rate, 4, cl.cinematic_file);
    cin.s_rate = LittleLong(cin.s_rate);
    FS_Read(&cin.s_width, 4, cl.cinematic_file);
    cin.s_width = LittleLong(cin.s_width);
    FS_Read(&cin.s_channels, 4, cl.cinematic_file);
    cin.s_channels = LittleLong(cin.s_channels);

    Huff1TableInit();

    cl.cinematicframe = 0;
    cin.pic = SCR_ReadNextFrame();
    cl.cinematictime = Sys_Milliseconds();
}
void Com_LoadBsp(const char *filename)
{
	ASSERT(filename != nullptr);
	ASSERT(!Com_IsBspLoaded());
	ASSERT(comBspGlob->loadedLumpData == nullptr);

	Com_Printf(0, "\n");
	Com_Printf(0, "Com_LoadBsp(%s)\n", filename);

	//
	// Get a handle to the file
	//
	int bspFileHandle;
	comBspGlob->fileSize = FS_FOpenFile(filename, &bspFileHandle);

	if(!bspFileHandle)
		Com_Error(0, "EXE_ERR_COULDNT_LOAD\x15%s", filename);

	//
	// Allocate space for the BSP header and read it
	//
	comBspGlob->header = (BspHeader *)Z_Malloc(comBspGlob->fileSize);

	if(FS_Read(comBspGlob->header, comBspGlob->fileSize, bspFileHandle) != comBspGlob->fileSize)
		Com_Error(0, "EXE_ERR_COULDNT_LOAD\x15%s", filename);

	//
	// Close the BSP file handle
	//
	FS_FCloseFile(bspFileHandle);

	//
	// Calculate the CRC32 of the BSP data
	//
	comBspGlob->checksum = crc32_calculate((const char *)comBspGlob->header, comBspGlob->fileSize, 0);

	Com_Printf(0, "\tSize:  %d\n", comBspGlob->fileSize);
	Com_Printf(0, "\tCRC32: %X\n", comBspGlob->checksum);

	//
	// Did the BSP load correctly, and is it a valid version?
	//
	if (Com_BspError())
	{
		Z_Free(comBspGlob->header);
		comBspGlob->header = nullptr;

		Com_Error(0, "EXE_ERR_WRONG_MAP_VERSION_NUM\x15%s", filename);
	}

	//
	// Mod tools assertion checks
	//
	ASSERT(strlen(filename) < ARRAYSIZE(comBspGlob->name));

	strcpy_s(comBspGlob->name, filename);

	ASSERT(Com_IsBspLoaded());

	Com_Printf(0, "Com_LoadBsp: End\n");
	Com_Printf(0, "\n");
}
kal_int32 SDS_RestoreNvramFilesFromRecord_Sim(kal_uint32* pBuf)
{
   kal_uint8 *p = (kal_uint8*)pBuf;
   kal_int32 fd;
   kal_uint32 len;
   kal_uint32 fileCount = 0;
   
   PackedDataHeadStruct *pHead;
   FileInfoStruct *pFileInfo = NULL;

   kal_uint16 buf[FS_MAX_PATH];
   
   ASSERT( ((kal_uint32)p)%4 == 0);
   
   pHead = (PackedDataHeadStruct*)p;

   p += pHead->headDataLen;


   while(fileCount < pHead->fileCount)
   {
      pFileInfo = (FileInfoStruct*)p;
      p += sizeof(FileInfoStruct);

      memcpy(buf, p, pFileInfo->fnLen);
      p += pFileInfo->fnLen;

      fd = FS_Open(buf, FS_OPEN_NO_DIR | FS_READ_ONLY);

      ASSERT(fd>=0);

      FS_GetFileSize(fd, &len);

      ASSERT(len == pFileInfo->contentLen);

      while(len)
      {
         kal_uint32 readLen = 0;
         kal_uint32 n = len;
         kal_int32 fsRet;
         
         if(n > sizeof(buf))
         {
            n = sizeof(buf);
         }

         memset(buf, 0xcd, sizeof(buf));
         fsRet = FS_Read(fd, buf, n, &readLen);

         ASSERT(fsRet >=0 && readLen == n);
         ASSERT(memcmp(p, buf, n) == 0);

         p += n;
         len -= n;
      }

      FS_Close(fd);
      p += (4-(pFileInfo->fnLen + pFileInfo->contentLen) % 4) % 4;

      fileCount++;
   }

   return fileCount;
}
Beispiel #17
0
/*
====================
CL_CgameSystemCalls

The cgame module is making a system call
====================
*/
intptr_t CL_CgameSystemCalls( intptr_t *args ) {
	switch ( args[0] ) {
	case CG_PRINT:
		Com_Printf( "%s", VMA( 1 ) );
		return 0;
	case CG_ERROR:
		Com_Error( ERR_DROP, "%s", VMA( 1 ) );
		return 0;
	case CG_MILLISECONDS:
		return Sys_Milliseconds();
	case CG_CVAR_REGISTER:
		Cvar_Register( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[4] );
		return 0;
	case CG_CVAR_UPDATE:
		Cvar_Update( VMA( 1 ) );
		return 0;
	case CG_CVAR_SET:
		Cvar_Set( VMA( 1 ), VMA( 2 ) );
		return 0;
	case CG_CVAR_VARIABLESTRINGBUFFER:
		Cvar_VariableStringBuffer( VMA( 1 ), VMA( 2 ), args[3] );
		return 0;
	case CG_ARGC:
		return Cmd_Argc();
	case CG_ARGV:
		Cmd_ArgvBuffer( args[1], VMA( 2 ), args[3] );
		return 0;
	case CG_ARGS:
		Cmd_ArgsBuffer( VMA( 1 ), args[2] );
		return 0;
	case CG_FS_FOPENFILE:
		return FS_FOpenFileByMode( VMA( 1 ), VMA( 2 ), args[3] );
	case CG_FS_READ:
		FS_Read( VMA( 1 ), args[2], args[3] );
		return 0;
	case CG_FS_WRITE:
		return FS_Write( VMA( 1 ), args[2], args[3] );
	case CG_FS_FCLOSEFILE:
		FS_FCloseFile( args[1] );
		return 0;
	case CG_SENDCONSOLECOMMAND:
		Cbuf_AddText( VMA( 1 ) );
		return 0;
	case CG_ADDCOMMAND:
		CL_AddCgameCommand( VMA( 1 ) );
		return 0;
	case CG_REMOVECOMMAND:
		Cmd_RemoveCommand( VMA( 1 ) );
		return 0;
	case CG_SENDCLIENTCOMMAND:
		CL_AddReliableCommand( VMA( 1 ) );
		return 0;
	case CG_UPDATESCREEN:
		// this is used during lengthy level loading, so pump message loop
//		Com_EventLoop();	// FIXME: if a server restarts here, BAD THINGS HAPPEN!
// We can't call Com_EventLoop here, a restart will crash and this _does_ happen
// if there is a map change while we are downloading at pk3.
// ZOID
		SCR_UpdateScreen();
		return 0;
	case CG_CM_LOADMAP:
		CL_CM_LoadMap( VMA( 1 ) );
		return 0;
	case CG_CM_NUMINLINEMODELS:
		return CM_NumInlineModels();
	case CG_CM_INLINEMODEL:
		return CM_InlineModel( args[1] );
	case CG_CM_TEMPBOXMODEL:
		return CM_TempBoxModel( VMA( 1 ), VMA( 2 ), qfalse );
	case CG_CM_TEMPCAPSULEMODEL:
		return CM_TempBoxModel( VMA( 1 ), VMA( 2 ), qtrue );
	case CG_CM_POINTCONTENTS:
		return CM_PointContents( VMA( 1 ), args[2] );
	case CG_CM_TRANSFORMEDPOINTCONTENTS:
		return CM_TransformedPointContents( VMA( 1 ), args[2], VMA( 3 ), VMA( 4 ) );
	case CG_CM_BOXTRACE:
		CM_BoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[6], args[7], /*int capsule*/ qfalse );
		return 0;
	case CG_CM_TRANSFORMEDBOXTRACE:
		CM_TransformedBoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[6], args[7], VMA( 8 ), VMA( 9 ), /*int capsule*/ qfalse );
		return 0;
	case CG_CM_CAPSULETRACE:
		CM_BoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[6], args[7], /*int capsule*/ qtrue );
		return 0;
	case CG_CM_TRANSFORMEDCAPSULETRACE:
		CM_TransformedBoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[6], args[7], VMA( 8 ), VMA( 9 ), /*int capsule*/ qtrue );
		return 0;
	case CG_CM_MARKFRAGMENTS:
		return re.MarkFragments( args[1], VMA( 2 ), VMA( 3 ), args[4], VMA( 5 ), args[6], VMA( 7 ) );
	case CG_S_STARTSOUND:
		S_StartSound( VMA( 1 ), args[2], args[3], args[4] );
		return 0;
//----(SA)	added
	case CG_S_STARTSOUNDEX:
		S_StartSoundEx( VMA( 1 ), args[2], args[3], args[4], args[5] );
		return 0;
//----(SA)	end
	case CG_S_STARTLOCALSOUND:
		S_StartLocalSound( args[1], args[2] );
		return 0;
	case CG_S_CLEARLOOPINGSOUNDS:
		S_ClearLoopingSounds(); // (SA) modified so no_pvs sounds can function
		return 0;
	case CG_S_ADDLOOPINGSOUND:
		// FIXME MrE: handling of looping sounds changed
		S_AddLoopingSound( args[1], VMA( 2 ), VMA( 3 ), args[4], args[5], args[6] );
		return 0;
	case CG_S_ADDREALLOOPINGSOUND:
		S_AddLoopingSound( args[1], VMA( 2 ), VMA( 3 ), args[4], args[5], args[6] );
		//S_AddRealLoopingSound( args[1], VMA(2), VMA(3), args[4], args[5] );
		return 0;
	case CG_S_STOPLOOPINGSOUND:
		// RF, not functional anymore, since we reverted to old looping code
		//S_StopLoopingSound( args[1] );
		return 0;
	case CG_S_UPDATEENTITYPOSITION:
		S_UpdateEntityPosition( args[1], VMA( 2 ) );
		return 0;
// Ridah, talking animations
	case CG_S_GETVOICEAMPLITUDE:
		return S_GetVoiceAmplitude( args[1] );
// done.
	case CG_S_RESPATIALIZE:
		S_Respatialize( args[1], VMA( 2 ), VMA( 3 ), args[4] );
		return 0;
	case CG_S_REGISTERSOUND:
#ifdef DOOMSOUND    ///// (SA) DOOMSOUND
		return S_RegisterSound( VMA( 1 ) );
#else
		return S_RegisterSound( VMA( 1 ), qfalse );
#endif  ///// (SA) DOOMSOUND
	case CG_S_STARTBACKGROUNDTRACK:
		S_StartBackgroundTrack( VMA( 1 ), VMA( 2 ) );
		return 0;
	case CG_S_STARTSTREAMINGSOUND:
		S_StartStreamingSound( VMA( 1 ), VMA( 2 ), args[3], args[4], args[5] );
		return 0;
	case CG_R_LOADWORLDMAP:
		re.LoadWorld( VMA( 1 ) );
		return 0;
	case CG_R_REGISTERMODEL:
		return re.RegisterModel( VMA( 1 ) );
	case CG_R_REGISTERSKIN:
		return re.RegisterSkin( VMA( 1 ) );

		//----(SA)	added
	case CG_R_GETSKINMODEL:
		return re.GetSkinModel( args[1], VMA( 2 ), VMA( 3 ) );
	case CG_R_GETMODELSHADER:
		return re.GetShaderFromModel( args[1], args[2], args[3] );
		//----(SA)	end

	case CG_R_REGISTERSHADER:
		return re.RegisterShader( VMA( 1 ) );
	case CG_R_REGISTERFONT:
		re.RegisterFont( VMA( 1 ), args[2], VMA( 3 ) );
	case CG_R_REGISTERSHADERNOMIP:
		return re.RegisterShaderNoMip( VMA( 1 ) );
	case CG_R_CLEARSCENE:
		re.ClearScene();
		return 0;
	case CG_R_ADDREFENTITYTOSCENE:
		re.AddRefEntityToScene( VMA( 1 ) );
		return 0;
	case CG_R_ADDPOLYTOSCENE:
		re.AddPolyToScene( args[1], args[2], VMA( 3 ) );
		return 0;
		// Ridah
	case CG_R_ADDPOLYSTOSCENE:
		re.AddPolysToScene( args[1], args[2], VMA( 3 ), args[4] );
		return 0;
		// done.
//	case CG_R_LIGHTFORPOINT:
//		return re.LightForPoint( VMA(1), VMA(2), VMA(3), VMA(4) );
	case CG_R_ADDLIGHTTOSCENE:
		re.AddLightToScene( VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[6] );
		return 0;
//	case CG_R_ADDADDITIVELIGHTTOSCENE:
//		re.AddAdditiveLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
//		return 0;
	case CG_R_ADDCORONATOSCENE:
		re.AddCoronaToScene( VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[6], args[7] );
		return 0;
	case CG_R_SETFOG:
		re.SetFog( args[1], args[2], args[3], VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ) );
		return 0;
	case CG_R_RENDERSCENE:
		re.RenderScene( VMA( 1 ) );
		return 0;
	case CG_R_SETCOLOR:
		re.SetColor( VMA( 1 ) );
		return 0;
	case CG_R_DRAWSTRETCHPIC:
		re.DrawStretchPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[9] );
		return 0;
	case CG_R_DRAWROTATEDPIC:
		re.DrawRotatedPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[9], VMF( 10 ) );
		return 0;
	case CG_R_DRAWSTRETCHPIC_GRADIENT:
		re.DrawStretchPicGradient( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[9], VMA( 10 ), args[11] );
		return 0;
	case CG_R_MODELBOUNDS:
		re.ModelBounds( args[1], VMA( 2 ), VMA( 3 ) );
		return 0;
	case CG_R_LERPTAG:
		return re.LerpTag( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[4] );
	case CG_GETGLCONFIG:
		CL_GetGlconfig( VMA( 1 ) );
		return 0;
	case CG_GETGAMESTATE:
		CL_GetGameState( VMA( 1 ) );
		return 0;
	case CG_GETCURRENTSNAPSHOTNUMBER:
		CL_GetCurrentSnapshotNumber( VMA( 1 ), VMA( 2 ) );
		return 0;
	case CG_GETSNAPSHOT:
		return CL_GetSnapshot( args[1], VMA( 2 ) );
	case CG_GETSERVERCOMMAND:
		return CL_GetServerCommand( args[1] );
	case CG_GETCURRENTCMDNUMBER:
		return CL_GetCurrentCmdNumber();
	case CG_GETUSERCMD:
		return CL_GetUserCmd( args[1], VMA( 2 ) );
	case CG_SETUSERCMDVALUE:
		CL_SetUserCmdValue( args[1], args[2], VMF( 3 ), args[4], args[5] );
		return 0;
	case CG_SETCLIENTLERPORIGIN:
		CL_SetClientLerpOrigin( VMF( 1 ), VMF( 2 ), VMF( 3 ) );
		return 0;
	case CG_MEMORY_REMAINING:
		return Hunk_MemoryRemaining();
	case CG_KEY_ISDOWN:
		return Key_IsDown( args[1] );
	case CG_KEY_GETCATCHER:
		return Key_GetCatcher();
	case CG_KEY_SETCATCHER:
		Key_SetCatcher( args[1] );
		return 0;
	case CG_KEY_GETKEY:
		return Key_GetKey( VMA( 1 ) );



	case CG_MEMSET:
		return (intptr_t)memset( VMA( 1 ), args[2], args[3] );
	case CG_MEMCPY:
		return (intptr_t)memcpy( VMA( 1 ), VMA( 2 ), args[3] );
	case CG_STRNCPY:
		return (intptr_t)strncpy( VMA( 1 ), VMA( 2 ), args[3] );
	case CG_SIN:
		return FloatAsInt( sin( VMF( 1 ) ) );
	case CG_COS:
		return FloatAsInt( cos( VMF( 1 ) ) );
	case CG_ATAN2:
		return FloatAsInt( atan2( VMF( 1 ), VMF( 2 ) ) );
	case CG_SQRT:
		return FloatAsInt( sqrt( VMF( 1 ) ) );
	case CG_FLOOR:
		return FloatAsInt( floor( VMF( 1 ) ) );
	case CG_CEIL:
		return FloatAsInt( ceil( VMF( 1 ) ) );
	case CG_ACOS:
		return FloatAsInt( Q_acos( VMF( 1 ) ) );

	case CG_PC_ADD_GLOBAL_DEFINE:
		return botlib_export->PC_AddGlobalDefine( VMA( 1 ) );
	case CG_PC_LOAD_SOURCE:
		return botlib_export->PC_LoadSourceHandle( VMA( 1 ) );
	case CG_PC_FREE_SOURCE:
		return botlib_export->PC_FreeSourceHandle( args[1] );
	case CG_PC_READ_TOKEN:
		return botlib_export->PC_ReadTokenHandle( args[1], VMA( 2 ) );
	case CG_PC_SOURCE_FILE_AND_LINE:
		return botlib_export->PC_SourceFileAndLine( args[1], VMA( 2 ), VMA( 3 ) );

	case CG_S_STOPBACKGROUNDTRACK:
		S_StopBackgroundTrack();
		return 0;

	case CG_REAL_TIME:
		return Com_RealTime( VMA( 1 ) );
	case CG_SNAPVECTOR:
		Sys_SnapVector( VMA( 1 ) );
		return 0;

	case CG_SENDMOVESPEEDSTOGAME:
		SV_SendMoveSpeedsToGame( args[1], VMA( 2 ) );
		return 0;

	case CG_CIN_PLAYCINEMATIC:
		return CIN_PlayCinematic( VMA( 1 ), args[2], args[3], args[4], args[5], args[6] );

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

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

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

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

	case CG_R_REMAP_SHADER:
		re.RemapShader( VMA( 1 ), VMA( 2 ), VMA( 3 ) );
		return 0;

	case CG_TESTPRINTINT:
		Com_Printf( "%s%i\n", VMA( 1 ), args[2] );
		return 0;
	case CG_TESTPRINTFLOAT:
		Com_Printf( "%s%f\n", VMA( 1 ), VMF( 2 ) );
		return 0;

	case CG_LOADCAMERA:
		return loadCamera( args[1], VMA( 2 ) );

	case CG_STARTCAMERA:
		startCamera( args[1], args[2] );
		return 0;

	case CG_GETCAMERAINFO:
		return getCameraInfo( args[1], args[2], VMA( 3 ), VMA( 4 ), VMA( 5 ) );

	case CG_GET_ENTITY_TOKEN:
		return re.GetEntityToken( VMA( 1 ), args[2] );

	case CG_INGAME_POPUP:
		if ( cls.state == CA_ACTIVE && !clc.demoplaying ) {
			// NERVE - SMF
			if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_PICKTEAM" ) ) {
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_PICKTEAM );
			} else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_PICKPLAYER" ) )    {
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_PICKPLAYER );
			} else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_QUICKMESSAGE" ) )    {
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_QUICKMESSAGE );
			} else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_QUICKMESSAGEALT" ) )    {
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_QUICKMESSAGEALT );
			} else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_LIMBO" ) )    {
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_LIMBO );
			} else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_AUTOUPDATE" ) )    {
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_AUTOUPDATE );
			}
			// -NERVE - SMF
			else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "hbook1" ) ) {   //----(SA)
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_BOOK1 );
			} else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "hbook2" ) )    { //----(SA)
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_BOOK2 );
			} else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "hbook3" ) )    { //----(SA)
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_BOOK3 );
			} else {
				VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_CLIPBOARD );
			}
		}
		return 0;

		// NERVE - SMF
	case CG_INGAME_CLOSEPOPUP:
		// if popup menu is up, then close it
		if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_LIMBO" ) ) {
			if ( VM_Call( uivm, UI_GET_ACTIVE_MENU ) == UIMENU_WM_LIMBO ) {
				VM_Call( uivm, UI_KEY_EVENT, K_ESCAPE, qtrue );
				VM_Call( uivm, UI_KEY_EVENT, K_ESCAPE, qtrue );
			}
		}
		return 0;

	case CG_LIMBOCHAT:
		if ( VMA( 1 ) ) {
			CL_AddToLimboChat( VMA( 1 ) );
		}
		return 0;

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

	case CG_KEY_SETBINDING:
		Key_SetBinding( args[1], VMA( 2 ) );
		return 0;

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

	case CG_TRANSLATE_STRING:
		CL_TranslateString( VMA( 1 ), VMA( 2 ) );
		return 0;
		// - NERVE - SMF
	default:
		Com_Error( ERR_DROP, "Bad cgame system trap: %i", args[0] );
	}
	return 0;
}
kal_int32 SDS_PackNvramFilesToRecord_Sim(kal_uint32* pBuf, const kal_uint16 **pDirList, const kal_uint16 **pFileList, kal_int32 fileCount)
{
   kal_int32 i;
   kal_uint8 *p = (kal_uint8*)pBuf;

   PackedDataHeadStruct *pHead;
   PACKED_DATA_INDEX *pIndex;

   ASSERT( ((kal_uint32)p)%4 == 0);
   
   pHead = (PackedDataHeadStruct*)p;
   memset(pHead, 0x00, sizeof(PackedDataHeadStruct));
   pHead->fileCount = fileCount;
   memcpy(pHead->head_tag, PACKED_DATA_HEAD_TAG, sizeof(PACKED_DATA_HEAD_TAG));
   
   p += sizeof(PackedDataHeadStruct);
   
   pIndex = (PACKED_DATA_INDEX*)p;
   p += sizeof(PACKED_DATA_INDEX)*fileCount;

   pHead->headDataLen = p-(kal_uint8*)pBuf;
      
   for(i=0; i<fileCount; i++)
   {
      kal_uint16 fileNameBuf[FS_MAX_PATH]; 
      FileInfoStruct fileInfo;
      kal_uint32 fnLen = SDS_ConcatPathAndFileName(fileNameBuf, pDirList[i], pFileList[i]);
      kal_int32 fileLen = SDS_GetFileSize(fileNameBuf);
      pIndex[i].checksum = SDS_CalcFilenameHash(fileNameBuf, fnLen);
      pIndex[i].offset = (kal_uint32)(p-(kal_uint8*)pBuf);

      fileInfo.contentLen = fileLen;
      fileInfo.fnLen = (fnLen+1)*2;

      memcpy(p, &fileInfo, sizeof(fileInfo));
      p += sizeof(fileInfo);

      memcpy(p, fileNameBuf, fileInfo.fnLen);
      p += fileInfo.fnLen;

      {
         kal_int32 status;
         kal_uint32 readLen;
         
         kal_int32 fd = FS_Open(fileNameBuf, FS_OPEN_NO_DIR | FS_READ_ONLY);
         ASSERT(fd >= 0);
         status = FS_Read(fd, p, fileLen, &readLen);
         ASSERT(status >= 0 && readLen == fileLen);
         FS_Close(fd);

         p += fileLen;
      }

      while((kal_uint32)p % 4)
      {
         *p++ = 0xcd;
      }
   }
   
   pHead->fileDataLen = p-(kal_uint8*)pBuf - pHead->headDataLen;

   return p-(kal_uint8*)pBuf;
}
Beispiel #19
0
void png_zip_read(png_structp png_ptr, png_bytep data, png_size_t length)
{
  FS_Read(data,1, length,file);
}
Beispiel #20
0
/*
=================
Stream_OpenMPG
=================
*/
stream_t *Stream_OpenMPG( const char *filename )
{
	mpeg_t	*mpegFile;
	stream_t	*stream;
	file_t	*file;
	long	filesize, read_len;
	char	tempbuff[FRAME_SIZE];

	file = FS_Open( filename, "rb", false );
	if( !file ) return NULL;

	filesize = FS_FileLength( file );
	if( filesize < FRAME_SIZE )
	{
		MsgDev( D_ERROR, "Stream_OpenMPG: %s is probably corrupted\n", filename );
		FS_Close( file );
		return NULL;
	}

	// at this point we have valid stream
	stream = Mem_Alloc( host.soundpool, sizeof( stream_t ));
	stream->file = file;
	stream->pos = 0;

	mpegFile = Mem_Alloc( host.soundpool, sizeof( mpeg_t ));

	// couldn't create decoder
	if( !create_decoder( mpegFile ))
	{
		MsgDev( D_ERROR, "Stream_OpenMPG: couldn't create decoder\n" );
		Mem_Free( mpegFile );
		Mem_Free( stream );
		FS_Close( file );
		return NULL;
	}

	read_len = FS_Read( file, tempbuff, sizeof( tempbuff ));
	if( read_len < sizeof( tempbuff ))
	{
		MsgDev( D_ERROR, "Stream_OpenMPG: %s is probably corrupted\n", filename );
		close_decoder( mpegFile );
		Mem_Free( mpegFile );
		Mem_Free( stream );
		FS_Close( file );
		return NULL;
	}

	// trying to read header
	if( !read_mpeg_header( mpegFile, tempbuff, sizeof( tempbuff ), filesize ))
	{
		MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", filename );
		close_decoder( mpegFile );
		Mem_Free( mpegFile );
		Mem_Free( stream );
		FS_Close( file );
		return NULL;
	}

	stream->buffsize = 0; // how many samples left from previous frame
	stream->channels = mpegFile->channels;
	stream->pos += mpegFile->outsize;
	stream->rate = mpegFile->rate;
	stream->width = 2;	// always 16 bit
	stream->ptr = mpegFile;
	stream->type = WF_MPGDATA;

	return stream;
}
Beispiel #21
0
void demoConvert( const char *oldName, const char *newBaseName, qboolean smoothen ) {
	fileHandle_t	oldHandle = 0;
	fileHandle_t	newHandle = 0;
	int				temp;
	int				oldSize;
	int				msgSequence;
	msg_t			oldMsg;
	byte			oldData[ MAX_MSGLEN ];
	int				oldTime, nextTime, fullTime;
	int				clientNum;
	demoFrame_t		*workFrame;
	int				parseEntitiesNum = 0;
	demoConvert_t	*convert;
	char			bigConfigString[BIG_INFO_STRING];
	int				bigConfigNumber;
	const char		*s;
	clSnapshot_t	*oldSnap = 0;
	clSnapshot_t	*newSnap;
	int				levelCount = 0;
	char			newName[MAX_OSPATH];

	oldSize = FS_FOpenFileRead( oldName, &oldHandle, qtrue );
	if (!oldHandle) {
		Com_Printf("Failed to open %s for conversion.", oldName);
		return;
	}
	/* Alloc some memory */
	convert = Z_Malloc( sizeof( demoConvert_t) );
	/* Initialize the first workframe's strings */
	while (oldSize > 0) {
		MSG_Init( &oldMsg, oldData, sizeof( oldData ) );
		/* Read the sequence number */
		if (FS_Read( &convert->messageNum, 4, oldHandle) != 4)
			goto conversionerror;
		convert->messageNum = LittleLong( convert->messageNum );
		oldSize -= 4;
		/* Read the message size */
		if (FS_Read( &oldMsg.cursize,4, oldHandle) != 4)
			goto conversionerror;
		oldSize -= 4;
		oldMsg.cursize = LittleLong( oldMsg.cursize );
		/* Negative size signals end of demo */
		if (oldMsg.cursize < 0)
			break;
		if ( oldMsg.cursize > oldMsg.maxsize ) 
			goto conversionerror;
		/* Read the actual message */
		if (FS_Read( oldMsg.data, oldMsg.cursize, oldHandle ) != oldMsg.cursize)
			goto conversionerror;
		oldSize -= oldMsg.cursize;
		// init the bitstream
		MSG_BeginReading( &oldMsg );
		// Skip the reliable sequence acknowledge number
		MSG_ReadLong( &oldMsg );
		//
		// parse the message
		//
		while ( 1 ) {
			byte cmd;
			if ( oldMsg.readcount > oldMsg.cursize ) {
				Com_Printf ("Demo conversion, read past end of server message.\n");
				goto conversionerror;
			}
            cmd = MSG_ReadByte( &oldMsg );
			if ( cmd == svc_EOF) {
                break;
			}
			workFrame = &convert->frames[ convert->frameIndex % DEMOCONVERTFRAMES ];
			// other commands
			switch ( cmd ) {
			default:
				Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message\n");
				break;			
			case svc_nop:
				break;
			case svc_serverCommand:
				temp = MSG_ReadLong( &oldMsg );
				s = MSG_ReadString( &oldMsg );
				if (temp<=msgSequence)
					break;
//				Com_Printf( " server command %s\n", s );
				msgSequence = temp;
				Cmd_TokenizeString( s );
	
				if ( !Q_stricmp( Cmd_Argv(0), "bcs0" ) ) {
					bigConfigNumber = atoi( Cmd_Argv(1) );
					Q_strncpyz( bigConfigString, Cmd_Argv(2), sizeof( bigConfigString ));
					break;
				}
				if ( !Q_stricmp( Cmd_Argv(0), "bcs1" ) ) {
					Q_strcat( bigConfigString, sizeof( bigConfigString ), Cmd_Argv(2));
					break;
				}
				if ( !Q_stricmp( Cmd_Argv(0), "bcs2" ) ) {
					Q_strcat( bigConfigString, sizeof( bigConfigString ), Cmd_Argv(2));
					demoFrameAddString( &workFrame->string, bigConfigNumber, bigConfigString );
					break;
				}
				if ( !Q_stricmp( Cmd_Argv(0), "cs" ) ) {
					int num = atoi( Cmd_Argv(1) );
					s = Cmd_ArgsFrom( 2 );
					demoFrameAddString( &workFrame->string, num, Cmd_ArgsFrom( 2 ) );
					break;
				}
				if ( clientNum >= 0 && clientNum < MAX_CLIENTS ) {
					int len = strlen( s ) + 1;
					char *dst;
					if (workFrame->commandUsed + len + 1 > sizeof( workFrame->commandData)) {
						Com_Printf("Overflowed state command data.\n");
						goto conversionerror;
					}
					dst = workFrame->commandData + workFrame->commandUsed;
					*dst = clientNum;
					Com_Memcpy( dst+1, s, len );
					workFrame->commandUsed += len + 1;
				}
				break;
			case svc_gamestate:
				if (newHandle) {
					FS_FCloseFile( newHandle );
					newHandle = 0;
				}
				if (levelCount) {
					Com_sprintf( newName, sizeof( newName ), "%s.%d.mme", newBaseName, levelCount );
				} else {
					Com_sprintf( newName, sizeof( newName ), "%s.mme", newBaseName );
				}
				fullTime = -1;
				clientNum = -1;
				oldTime = -1;
				Com_Memset( convert, 0, sizeof( *convert ));
				convert->frames[0].string.used = 1;
				levelCount++;
				newHandle = FS_FOpenFileWrite( newName );
				if (!newHandle) {
					Com_Printf("Failed to open %s for target conversion target.\n", newName);
					goto conversionerror;
					return;
				} else {
					FS_Write ( demoHeader, strlen( demoHeader ), newHandle );
				}
				Com_sprintf( newName, sizeof( newName ), "%s.txt", newBaseName );
				workFrame = &convert->frames[ convert->frameIndex % DEMOCONVERTFRAMES ];
				msgSequence = MSG_ReadLong( &oldMsg );
				while( 1 ) {
					cmd = MSG_ReadByte( &oldMsg );
					if (cmd == svc_EOF)
						break;
					if ( cmd == svc_configstring) {
						int		num;
						const char *s;
						num = MSG_ReadShort( &oldMsg );
						s = MSG_ReadBigString( &oldMsg );
						demoFrameAddString( &workFrame->string, num, s );
					} else if ( cmd == svc_baseline ) {
						int num = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
						if ( num < 0 || num >= MAX_GENTITIES ) {
							Com_Printf( "Baseline number out of range: %i.\n", num );
							goto conversionerror;
						}
						MSG_ReadDeltaEntity( &oldMsg, &demoNullEntityState, &convert->entityBaselines[num], num );
					} else {
						Com_Printf( "Unknown block while converting demo gamestate.\n" );
						goto conversionerror;
					}
				}
				clientNum = MSG_ReadLong( &oldMsg );
				/* Skip the checksum feed */
				MSG_ReadLong( &oldMsg );
				break;
			case svc_snapshot:
				nextTime = MSG_ReadLong( &oldMsg );
				/* Delta number, not needed */
				newSnap = &convert->snapshots[convert->messageNum & PACKET_MASK];
				Com_Memset (newSnap, 0, sizeof(*newSnap));
				newSnap->deltaNum = MSG_ReadByte( &oldMsg );
				newSnap->messageNum = convert->messageNum;
				if (!newSnap->deltaNum) {
					newSnap->deltaNum = -1;
					newSnap->valid = qtrue;		// uncompressed frame
					oldSnap  = NULL;
				} else {
					newSnap->deltaNum = newSnap->messageNum - newSnap->deltaNum;
					oldSnap = &convert->snapshots[newSnap->deltaNum & PACKET_MASK];
					if (!oldSnap->valid) {
						Com_Printf( "Delta snapshot without base.\n" );
						goto conversionerror;
					} else if (oldSnap->messageNum != newSnap->deltaNum) {
						// The frame that the server did the delta from
						// is too old, so we can't reconstruct it properly.
						Com_Printf ("Delta frame too old.\n");
					} else if ( parseEntitiesNum - oldSnap->parseEntitiesNum > MAX_PARSE_ENTITIES-128 ) {
						Com_Printf ("Delta parseEntitiesNum too old.\n");
					} else {
						newSnap->valid = qtrue;	// valid delta parse
					}
				}

				/* Snapflags, not needed */
				newSnap->snapFlags = MSG_ReadByte( &oldMsg );
				// read areamask
				workFrame->areaUsed = MSG_ReadByte( &oldMsg );
				MSG_ReadData( &oldMsg, workFrame->areamask, workFrame->areaUsed );
				if (clientNum <0 || clientNum >= MAX_CLIENTS) {
					Com_Printf("Got snapshot with invalid client.\n");
					goto conversionerror;
				}
				MSG_ReadDeltaPlayerstate( &oldMsg, oldSnap ? &oldSnap->ps : &demoNullPlayerState, &newSnap->ps );
				/* Read the individual entities */
				newSnap->parseEntitiesNum = parseEntitiesNum;
				newSnap->numEntities = 0;
				Com_Memset( workFrame->entityData, 0, sizeof( workFrame->entityData ));

				/* The beast that is entity parsing */
				{
				int			newnum;
				entityState_t	*oldstate, *newstate;
				int			oldindex = 0;
				int			oldnum;
				newnum = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
				while ( 1 ) {
					// read the entity index number
					if (oldSnap && oldindex < oldSnap->numEntities) {
						oldstate = &convert->parseEntities[(oldSnap->parseEntitiesNum + oldindex) & (MAX_PARSE_ENTITIES-1)];
						oldnum = oldstate->number;
					} else {
						oldstate = 0;
						oldnum = 99999;
					}
					newstate = &convert->parseEntities[parseEntitiesNum];
					if ( !oldstate && (newnum == (MAX_GENTITIES-1))) {
						break;
					} else if ( oldnum < newnum ) {
						*newstate = *oldstate;
						oldindex++;
					} else if (oldnum == newnum) {
						oldindex++;
						MSG_ReadDeltaEntity( &oldMsg, oldstate, newstate, newnum );
						if ( newstate->number != MAX_GENTITIES-1)
							workFrame->entityData[ newstate->number ] = 1;
						newnum = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
					} else if (oldnum > newnum) {
						MSG_ReadDeltaEntity( &oldMsg, &convert->entityBaselines[newnum], newstate , newnum );
						if ( newstate->number != MAX_GENTITIES-1)
							workFrame->entityData[ newstate->number ] = 1;
						newnum = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
					}
					if (newstate->number == MAX_GENTITIES-1)
						continue;
					parseEntitiesNum++;
					parseEntitiesNum &= (MAX_PARSE_ENTITIES-1);
					newSnap->numEntities++;
				}}
				/* Stop processing this further since it's an invalid snap due to lack of delta data */
				if (!newSnap->valid)
					break;

				/* Skipped snapshots will be set invalid in the circular buffer */
				if ( newSnap->messageNum - convert->lastMessageNum >= PACKET_BACKUP ) {
					convert->lastMessageNum = newSnap->messageNum - ( PACKET_BACKUP - 1 );
				}
				for ( ; convert->lastMessageNum < newSnap->messageNum ; convert->lastMessageNum++ ) {
					convert->snapshots[convert->lastMessageNum & PACKET_MASK].valid = qfalse;
				}
				convert->lastMessageNum = newSnap->messageNum + 1;

				/* compress the frame into the new format */
				if (nextTime > oldTime) {
					demoFrame_t *cleanFrame;
					int writeIndex;
					for (temp = 0;temp<newSnap->numEntities;temp++) {
						int p = (newSnap->parseEntitiesNum+temp) & (MAX_PARSE_ENTITIES-1);
						entityState_t *newState = &convert->parseEntities[p];
						workFrame->entities[newState->number] = *newState;
					}
					workFrame->clientData[clientNum] = 1;
					workFrame->clients[clientNum] = newSnap->ps;
					workFrame->serverTime = nextTime;

					/* Which frame from the cache to save */
					writeIndex = convert->frameIndex - (DEMOCONVERTFRAMES/2);
					if (writeIndex >= 0) {
						const demoFrame_t *newFrame;
						msg_t writeMsg;
						// init the message
						MSG_Init( &writeMsg, demoBuffer, sizeof (demoBuffer));
						MSG_Clear( &writeMsg );
						MSG_Bitstream( &writeMsg );
						newFrame = &convert->frames[ writeIndex  % DEMOCONVERTFRAMES];
						if ( smoothen )
							demoFrameInterpolate( convert->frames, DEMOCONVERTFRAMES, writeIndex );
						if ( nextTime > fullTime || writeIndex <= 0 ) {
							/* Plan the next time for a full write */
							fullTime = nextTime + 2000;
							demoFramePack( &writeMsg, newFrame, 0 );
						} else {
							const demoFrame_t *oldFrame = &convert->frames[ ( writeIndex -1 ) % DEMOCONVERTFRAMES];
							demoFramePack( &writeMsg, newFrame, oldFrame );
						}
						/* Write away the new data in the msg queue */
						temp = LittleLong( writeMsg.cursize );
						FS_Write (&temp, 4, newHandle );
						FS_Write ( writeMsg.data , writeMsg.cursize, newHandle );
					}

					/* Clean up the upcoming frame for all new changes */
					convert->frameIndex++;
					cleanFrame = &convert->frames[ convert->frameIndex % DEMOCONVERTFRAMES];
					cleanFrame->serverTime = 0;
					for (temp = 0;temp<MAX_GENTITIES;temp++)
						cleanFrame->entities[temp].number = MAX_GENTITIES-1;
					Com_Memset( cleanFrame->clientData, 0, sizeof ( cleanFrame->clientData ));
					Com_Memcpy( cleanFrame->string.data, workFrame->string.data, workFrame->string.used );
					Com_Memcpy( cleanFrame->string.offsets, workFrame->string.offsets, sizeof( workFrame->string.offsets ));
					cleanFrame->string.used = workFrame->string.used;
					cleanFrame->commandUsed = 0;
					/* keep track of this last frame's time */
					oldTime = nextTime;
				}
				break;
			case svc_download:
				// read block number
				temp = MSG_ReadShort ( &oldMsg );
				if (!temp)	//0 block, read file size
					MSG_ReadLong( &oldMsg );
				// read block size
				temp = MSG_ReadShort ( &oldMsg );
				// read the data block
				for ( ;temp>0;temp--)
					MSG_ReadByte( &oldMsg );
				break;
			}
		}
	}
conversionerror:
	FS_FCloseFile( oldHandle );
	FS_FCloseFile( newHandle );
	Z_Free( convert );
	return;
}
Beispiel #22
0
/*
=================
Stream_ReadMPG

assume stream is valid
=================
*/
long Stream_ReadMPG( stream_t *stream, long needBytes, void *buffer )
{
	// buffer handling
	int	bytesWritten = 0;
	int	result;
	mpeg_t	*mpg;

	mpg = (mpeg_t *)stream->ptr;
	ASSERT( mpg != NULL );

	while( 1 )
	{
		char	tempbuff[FRAME_SIZE];
		long	read_len, outsize;
		byte	*data;

		if( !stream->buffsize )
		{
			if( stream->timejump )
			{
				int numReads = 0;

				// flush all the previous data				
				while( read_mpeg_stream( mpg, NULL, 0 ) == MP3_OK && numReads++ < 255 );
				read_len = FS_Read( stream->file, tempbuff, sizeof( tempbuff ));
				result = read_mpeg_stream( mpg, tempbuff, read_len );
				stream->timejump = false;
				bytesWritten = 0;
			}
			else result = read_mpeg_stream( mpg, NULL, 0 );

			stream->pos += mpg->outsize;

			if( result != MP3_OK )
			{
				// if there are no bytes remainig so we can decompress the new frame
				read_len = FS_Read( stream->file, tempbuff, sizeof( tempbuff ));
				result = read_mpeg_stream( mpg, tempbuff, read_len );
				stream->pos += mpg->outsize;

				if( result != MP3_OK )
					break; // there was end of the stream
			}
		}

		// check remaining size
		if( bytesWritten + mpg->outsize > needBytes )
			outsize = ( needBytes - bytesWritten ); 
		else outsize = mpg->outsize;

		// copy raw sample to output buffer
		data = (byte *)buffer + bytesWritten;
		Q_memcpy( data, &mpg->out[stream->buffsize], outsize );
		bytesWritten += outsize;
		mpg->outsize -= outsize;
		stream->buffsize += outsize;

		// continue from this sample on a next call
		if( bytesWritten >= needBytes )
			return bytesWritten;

		stream->buffsize = 0; // no bytes remaining
	}

	return 0;
}
Beispiel #23
0
/*
* CM_LoadMapMessage
*/
char *CM_LoadMapMessage( char *name, char *message, int size )
{
	int file, len;
	qbyte h_v[8];
	char *data, *entitystring;
	lump_t l;
	qboolean isworld;
	char key[MAX_KEY], value[MAX_VALUE], *token;
	const modelFormatDescr_t *descr;
	const bspFormatDesc_t *bspFormat = NULL;

	*message = '\0';

	len = FS_FOpenFile( name, &file, FS_READ );
	if( !file || len < 1 )
	{
		if( file )
			FS_FCloseFile( file );
		return message;
	}

	FS_Read( h_v, 4 + sizeof( int ), file );
	descr = Com_FindFormatDescriptor( cm_supportedformats, h_v, &bspFormat );
	if( !descr )
	{
		Com_Printf( "CM_LoadMapMessage: %s: unknown bsp format\n", name );
		FS_FCloseFile( file );
		return message;
	}

	FS_Seek( file, descr->headerLen + sizeof( int ) + sizeof( lump_t ) * bspFormat->entityLumpNum, FS_SEEK_SET );

	FS_Read( &l.fileofs, sizeof( l.fileofs ), file );
	l.fileofs = LittleLong( l.fileofs );

	FS_Read( &l.filelen, sizeof( l.filelen ), file );
	l.filelen = LittleLong( l.filelen );

	if( !l.filelen )
	{
		FS_FCloseFile( file );
		return message;
	}

	FS_Seek( file, l.fileofs, FS_SEEK_SET );

	entitystring = Mem_TempMalloc( l.filelen );
	FS_Read( entitystring, l.filelen, file );

	FS_FCloseFile( file );

	for( data = entitystring; ( token = COM_Parse( &data ) ) && token[0] == '{'; )
	{
		isworld = qtrue;

		while( 1 )
		{
			token = COM_Parse( &data );
			if( !token[0] || token[0] == '}' )
				break; // end of entity

			Q_strncpyz( key, token, sizeof( key ) );
			while( key[strlen( key )-1] == ' ' )  // remove trailing spaces
				key[strlen( key )-1] = 0;

			token = COM_Parse( &data );
			if( !token[0] )
				break; // error

			Q_strncpyz( value, token, sizeof( value ) );

			// now that we have the key pair worked out...
			if( !strcmp( key, "classname" ) )
			{
				if( strcmp( value, "worldspawn" ) )
					isworld = qfalse;
			}
			else if( !strcmp( key, "message" ) )
			{
				Q_strncpyz( message, token, size );
				break;
			}
		}

		if( isworld )
			break;
	}

	Mem_Free( entitystring );

	return message;
}
Beispiel #24
0
/*
=================
CL_ReadDemoMessage
=================
*/
void CL_ReadDemoMessage(void)
{
	int   r;
	msg_t buf;
	byte  bufData[MAX_MSGLEN];
	int   s;

	if (!clc.demofile)
	{
		CL_DemoCompleted();
		return;
	}

#if NEW_DEMOFUNC
	di.numSnaps++;

	if (di.snapCount < maxRewindBackups &&
	    ((!di.gotFirstSnap  &&  !(cls.state >= CA_CONNECTED && cls.state < CA_PRIMED))
	     || (di.gotFirstSnap  &&  di.numSnaps % (di.snapsInDemo / maxRewindBackups) == 0)))
	{
		rewindBackups_t *rb;

		if (!di.skipSnap)
		{
			// first snap triggers loading screen when rewinding
			di.skipSnap = qtrue;
			goto keep_reading;
		}

		di.gotFirstSnap = qtrue;
		rb              = &rewindBackups[di.snapCount];

		if (!rb->valid)
		{
			rb->valid     = qtrue;
			rb->numSnaps  = di.numSnaps;
			rb->seekPoint = FS_FTell(clc.demofile);

			memcpy(&rb->cl, &cl, sizeof(clientActive_t));
			memcpy(&rb->clc, &clc, sizeof(clientConnection_t));
			memcpy(&rb->cls, &cls, sizeof(clientStatic_t));
		}
		di.snapCount++;
	}

keep_reading:

#endif

	// get the sequence number
	r = FS_Read(&s, 4, clc.demofile);
	if (r != 4)
	{
		CL_DemoCompleted();
		return;
	}

	clc.serverMessageSequence = LittleLong(s);

	// init the message
	MSG_Init(&buf, bufData, sizeof(bufData));

	// get the length
	r = FS_Read(&buf.cursize, 4, clc.demofile);

	if (r != 4)
	{
		CL_DemoCompleted();
		return;
	}
	buf.cursize = LittleLong(buf.cursize);
	if (buf.cursize == -1)
	{
		CL_DemoCompleted();
		return;
	}

	if (buf.cursize > buf.maxsize)
	{
		Com_FuncDrop("demoMsglen > MAX_MSGLEN");
	}

	r = FS_Read(buf.data, buf.cursize, clc.demofile);
	if (r != buf.cursize)
	{
		Com_FuncPrinf("Demo file was truncated.\n");
		CL_DemoCompleted();
		return;
	}

	clc.lastPacketTime = cls.realtime;
	buf.readcount      = 0;
	CL_ParseServerMessage(&buf);
}
Beispiel #25
0
/*
==================
SV_WriteDownloadToClient

Check to see if the client wants a file, open it if needed and start pumping the client
Fill up msg with data
==================
*/
void SV_WriteDownloadToClient( client_t *cl , msg_t *msg )
{
	int curindex;
	int rate;
	int blockspersnap;
	qboolean legalPacket;
	char errorMessage[1024];

	if (!*cl->downloadName)
		return;	// Nothing being downloaded

	if (!cl->download) {
		// We open the file here

		Com_Printf( "clientDownload: %d : begining \"%s\"\n", (int)(cl - svs.clients), cl->downloadName );

		legalPacket = FS_MV_VerifyDownloadPath(va("%s", cl->downloadName)) ? qtrue : qfalse;

		if (!sv_allowDownload->integer || !legalPacket ||
			( cl->downloadSize = FS_SV_FOpenFileRead( cl->downloadName, &cl->download ) ) <= 0 ) {
			// cannot auto-download file
			if (!legalPacket) {
				Com_Printf("clientDownload: %d : tried to download unreferenced file \"%s\"\n", (int)(cl - svs.clients), cl->downloadName);
				Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload pk3 file \"%s\"", cl->downloadName);
			} else if ( !sv_allowDownload->integer ) {
				Com_Printf("clientDownload: %d : \"%s\" download disabled", (int)(cl - svs.clients), cl->downloadName);
				if (sv_pure->integer) {
					Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n"
										"You will need to get this file elsewhere before you "
										"can connect to this pure server.\n", cl->downloadName);
				} else {
					Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n"
										"Set autodownload to No in your settings and you might be "
										"able to connect if you do have the file.\n", cl->downloadName);
				}
			} else {
				Com_Printf("clientDownload: %d : \"%s\" file not found on server\n", (int)(cl - svs.clients), cl->downloadName);
				Com_sprintf(errorMessage, sizeof(errorMessage), "File \"%s\" not found on server for autodownloading.\n", cl->downloadName);
			}
			MSG_WriteByte( msg, svc_download );
			MSG_WriteShort( msg, 0 ); // client is expecting block zero
			MSG_WriteLong( msg, -1 ); // illegal file size
			MSG_WriteString( msg, errorMessage );

			*cl->downloadName = 0;
			return;
		}

		// Init
		cl->downloadCurrentBlock = cl->downloadClientBlock = cl->downloadXmitBlock = 0;
		cl->downloadCount = 0;
		cl->downloadEOF = qfalse;
	}

	// Perform any reads that we need to
	while (cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW &&
		cl->downloadSize != cl->downloadCount) {

		curindex = (cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW);

		if (!cl->downloadBlocks[curindex])
			cl->downloadBlocks[curindex] = (unsigned char *)Z_Malloc( MAX_DOWNLOAD_BLKSIZE, TAG_DOWNLOAD, qtrue );

		cl->downloadBlockSize[curindex] = FS_Read( cl->downloadBlocks[curindex], MAX_DOWNLOAD_BLKSIZE, cl->download );

		if (cl->downloadBlockSize[curindex] < 0) {
			// EOF right now
			cl->downloadCount = cl->downloadSize;
			break;
		}

		cl->downloadCount += cl->downloadBlockSize[curindex];

		// Load in next block
		cl->downloadCurrentBlock++;
	}

	// Check to see if we have eof condition and add the EOF block
	if (cl->downloadCount == cl->downloadSize &&
		!cl->downloadEOF &&
		cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW) {

		cl->downloadBlockSize[cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW] = 0;
		cl->downloadCurrentBlock++;

		cl->downloadEOF = qtrue;  // We have added the EOF block
	}

	// Loop up to window size times based on how many blocks we can fit in the
	// client snapMsec and rate

	// based on the rate, how many bytes can we fit in the snapMsec time of the client
	// normal rate / snapshotMsec calculation
	rate = cl->rate;
	if ( sv_maxRate->integer ) {
		if ( sv_maxRate->integer < 1000 ) {
			Cvar_Set( "sv_MaxRate", "1000" );
		}
		if ( sv_maxRate->integer < rate ) {
			rate = sv_maxRate->integer;
		}
	}

	if (!rate) {
		blockspersnap = 1;
	} else {
		blockspersnap = ( (rate * cl->snapshotMsec) / 1000 + MAX_DOWNLOAD_BLKSIZE ) /
			MAX_DOWNLOAD_BLKSIZE;
	}

	if (blockspersnap < 0)
		blockspersnap = 1;

	while (blockspersnap--) {

		// Write out the next section of the file, if we have already reached our window,
		// automatically start retransmitting

		if (cl->downloadClientBlock == cl->downloadCurrentBlock)
			return; // Nothing to transmit

		if (cl->downloadXmitBlock == cl->downloadCurrentBlock) {
			// We have transmitted the complete window, should we start resending?

			//FIXME:  This uses a hardcoded one second timeout for lost blocks
			//the timeout should be based on client rate somehow
			if (svs.time - cl->downloadSendTime > 1000)
				cl->downloadXmitBlock = cl->downloadClientBlock;
			else
				return;
		}

		// Send current block
		curindex = (cl->downloadXmitBlock % MAX_DOWNLOAD_WINDOW);

		MSG_WriteByte( msg, svc_download );
		MSG_WriteShort( msg, cl->downloadXmitBlock );

		// block zero is special, contains file size
		if ( cl->downloadXmitBlock == 0 )
			MSG_WriteLong( msg, cl->downloadSize );

		MSG_WriteShort( msg, cl->downloadBlockSize[curindex] );

		// Write the block
		if ( cl->downloadBlockSize[curindex] ) {
			MSG_WriteData( msg, cl->downloadBlocks[curindex], cl->downloadBlockSize[curindex] );
		}

		Com_DPrintf( "clientDownload: %d : writing block %d\n", (int)(cl - svs.clients), cl->downloadXmitBlock );

		// Move on to the next block
		// It will get sent with next snap shot.  The rate will keep us in line.
		cl->downloadXmitBlock++;

		cl->downloadSendTime = svs.time;
	}
}
Beispiel #26
0
qboolean CL_PeekSnapshot(int snapshotNumber, snapshot_t *snapshot)
{
	clSnapshot_t *clSnap;
	clSnapshot_t csn;
	int          i, count;
	int          origPosition;
	int          cmd;
	//char         *s;
	char     buffer[16];
	qboolean success = qfalse;
	int      r;
	msg_t    buf;
	byte     bufData[MAX_MSGLEN];
	int      j;
	int      lastPacketTimeOrig;
	int      parseEntitiesNumOrig;
	int      currentSnapNum;
	//int      serverMessageSequence;

	clSnap = &csn;

	if (!clc.demoplaying)
	{
		return qfalse;
	}

	if (snapshotNumber <= cl.snap.messageNum)
	{
		success = CL_GetSnapshot(snapshotNumber, snapshot);
		if (!success)
		{
			Com_FuncDPrinf("snapshot number outside of backup buffer\n");
			return qfalse;
		}
		return qtrue;
	}

	if (snapshotNumber > cl.snap.messageNum + 1)
	{
		Com_FuncDPrinf("FIXME CL_PeekSnapshot  %d >  cl.snap.messageNum + 1 (%d)\n", snapshotNumber, cl.snap.messageNum);
		//return qfalse;
	}

	parseEntitiesNumOrig = cl.parseEntitiesNum;
	lastPacketTimeOrig   = clc.lastPacketTime;
	// CL_ReadDemoMessage()
	origPosition = FS_FTell(clc.demofile);

	currentSnapNum = cl.snap.messageNum;

	for (j = 0; j < snapshotNumber - currentSnapNum; j++)
	{
		// get the sequence number
		memset(buffer, 0, sizeof(buffer));
		r = FS_Read(&buffer, 4, clc.demofile);
		if (r != 4)
		{
			Com_FuncDPrinf("couldn't read sequence number\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qfalse;
		}
		//serverMessageSequence = LittleLong(*((int *)buffer));

		// init the message
		memset(&buf, 0, sizeof(msg_t));
		MSG_Init(&buf, bufData, sizeof(bufData));

		// get the length
		r = FS_Read(&buf.cursize, 4, clc.demofile);
		if (r != 4)
		{
			Com_FuncDPrinf("couldn't get length\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qfalse;
		}

		buf.cursize = LittleLong(buf.cursize);
		if (buf.cursize == -1)
		{
			Com_FuncDPrinf("buf.cursize == -1\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qfalse;
		}

		if (buf.cursize > buf.maxsize)
		{
			Com_FuncDrop("demoMsglen > MAX_MSGLEN");
		}

		r = FS_Read(buf.data, buf.cursize, clc.demofile);
		if (r != buf.cursize)
		{
			Com_FuncDPrinf("Demo file was truncated.\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qfalse;
		}

		clc.lastPacketTime = cls.realtime;
		buf.readcount      = 0;

		MSG_Bitstream(&buf);
		// get the reliable sequence acknowledge number
		MSG_ReadLong(&buf);

		// parse the message
		while (qtrue)
		{
			if (buf.readcount > buf.cursize)
			{
				Com_FuncDrop("read past end of server message");
				break;
			}

			cmd = MSG_ReadByte(&buf);

			if (cmd == svc_EOF)
			{
				break;
			}
			success = qfalse;

			switch (cmd)
			{
			default:
				Com_FuncDrop("Illegible server message");
				break;
			case svc_nop:
				break;
			case svc_serverCommand:
				MSG_ReadLong(&buf);  // seq
				//s = MSG_ReadString(&buf);
				MSG_ReadString(&buf);
				break;
			case svc_gamestate:
				Com_FuncDPrinf("FIXME gamestate\n");
				goto alldone;
				break;
			case svc_snapshot:
				// TODO: changed this check if it works
				CL_ParseSnapshot(&buf);
				if (cl.snap.valid)
				{
					success = qtrue;
				}
				break;
			case svc_download:
				Com_FuncDPrinf("FIXME download\n");
				goto alldone;
				break;
			}
		}

alldone:

		if (!success)
		{
			Com_FuncDPrinf("failed\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return success;
		}

		// FIXME other ents not supported yet

		// if the entities in the frame have fallen out of their
		// circular buffer, we can't return it
		if (cl.parseEntitiesNum - clSnap->parseEntitiesNum >= MAX_PARSE_ENTITIES)
		{
			Com_FuncDPrinf("cl.parseEntitiesNum - clSnap->parseEntitiesNum >= MAX_PARSE_ENTITIES");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qtrue;  // FIXME if you fix other ents
		}

		// write the snapshot
		snapshot->snapFlags             = clSnap->snapFlags;
		snapshot->serverCommandSequence = clSnap->serverCommandNum;
		snapshot->ping                  = clSnap->ping;
		snapshot->serverTime            = clSnap->serverTime;
		Com_Memcpy(snapshot->areamask, clSnap->areamask, sizeof(snapshot->areamask));
		snapshot->ps = clSnap->ps;
		count        = clSnap->numEntities;

		if (count > MAX_ENTITIES_IN_SNAPSHOT)
		{
			Com_FuncDPrinf("truncated %i entities to %i\n", count, MAX_ENTITIES_IN_SNAPSHOT);
			count = MAX_ENTITIES_IN_SNAPSHOT;
		}

		snapshot->numEntities = count;
		for (i = 0; i < count; i++)
		{
			snapshot->entities[i] = cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
		}

	}

	FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
	clc.lastPacketTime  = lastPacketTimeOrig;
	cl.parseEntitiesNum = parseEntitiesNumOrig;
	// TODO: configstring changes and server commands!!!

	return qtrue;
}
/*
====================
CL_CgameSystemCalls

The cgame module is making a system call
====================
*/
intptr_t CL_CgameSystemCalls( intptr_t *args ) {
	switch( args[0] ) {
	case CG_PRINT:
		Com_Printf( "%s", VMA(1) );
		return 0;
	case CG_FATAL_ERROR:
		Com_Error( ERR_DROP, "%s", VMA(1) );
		return 0;
	case CG_MILLISECONDS:
		return Sys_Milliseconds();
	case CG_CVAR_REGISTER:
		Cvar_Register( VMA(1), VMA(2), VMA(3), args[4] ); 
		return 0;
	case CG_CVAR_UPDATE:
		Cvar_Update( VMA(1) );
		return 0;
	case CG_CVAR_SET:
		Cvar_Set( VMA(1), VMA(2) );
		return 0;
	case CG_CVAR_VARIABLESTRINGBUFFER:
		Cvar_VariableStringBuffer( VMA(1), VMA(2), args[3] );
		return 0;
	case CG_ARGC:
		return Cmd_Argc();
	case CG_ARGV:
		Cmd_ArgvBuffer( args[1], VMA(2), args[3] );
		return 0;
	case CG_ARGVI:
		return atoi( Cmd_Argv( args[1] ) );
	case CG_ARGS:
		Cmd_ArgsBuffer( VMA(1), args[2] );
		return 0;
	case CG_CMD_EXECUTETEXT:
		Cbuf_ExecuteText( args[1], VMA(2) );
		return 0;
	case CG_FS_FOPENFILE:
		return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] );
	case CG_FS_READ:
		FS_Read( VMA(1), args[2], args[3] );
		return 0;
	case CG_FS_WRITE:
		FS_Write( VMA(1), args[2], args[3] );
		return 0;
	case CG_FS_FCLOSEFILE:
		FS_FCloseFile( args[1] );
		return 0;
	case CG_SENDCONSOLECOMMAND:
		Cbuf_AddText( VMA(1) );
		return 0;
	case CG_FORWARDCOMMAND:
		VM_Call( uivm, UI_CONSOLE_COMMAND, cls.realtime );
		return 0;
	case CG_ADDCOMMAND:
		CL_AddCgameCommand( VMA(1) );
		return 0;
	case CG_REMOVECOMMAND:
		Cmd_RemoveCommand( VMA(1) );
		return 0;
	case CG_SENDCLIENTCOMMAND:
		CL_AddReliableCommand( VMA(1) );
		return 0;
	case CG_UPDATESCREEN:
		// this is used during lengthy level loading, so pump message loop
//		Com_EventLoop();	// FIXME: if a server restarts here, BAD THINGS HAPPEN!
// We can't call Com_EventLoop here, a restart will crash and this _does_ happen
// if there is a map change while we are downloading at pk3.
// ZOID
		SCR_UpdateScreen();
		return 0;
	case CG_CM_LOADMAP:
		CL_CM_LoadMap( VMA(1) );
		return 0;
	case CG_CM_NUMINLINEMODELS:
		return CM_NumInlineModels();
	case CG_CM_INLINEMODEL:
		return CM_InlineModel( args[1] );
	case CG_CM_TEMPBOXMODEL:
		return CM_TempBoxModel( VMA(1), VMA(2), /*int capsule*/ qfalse );
	case CG_CM_TEMPCAPSULEMODEL:
		return CM_TempBoxModel( VMA(1), VMA(2), /*int capsule*/ qtrue );
	case CG_CM_POINTCONTENTS:
		return CM_PointContents( VMA(1), args[2] );
	case CG_CM_TRANSFORMEDPOINTCONTENTS:
		return CM_TransformedPointContents( VMA(1), args[2], VMA(3), VMA(4) );
	case CG_CM_BOXTRACE:
		CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qfalse );
		return 0;
	case CG_CM_CAPSULETRACE:
		CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qtrue );
		return 0;
	case CG_CM_TRANSFORMEDBOXTRACE:
		CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qfalse );
		return 0;
	case CG_CM_TRANSFORMEDCAPSULETRACE:
		CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qtrue );
		return 0;
	case CG_CM_MARKFRAGMENTS:
		return re.MarkFragments( args[1], VMA(2), VMA(3), args[4], VMA(5), args[6], VMA(7) );
	case CG_S_STARTSOUND:
		S_StartSound( VMA(1), args[2], args[3], args[4] );
		return 0;
	case CG_S_STARTLOCALSOUND:
		S_StartLocalSound( args[1], args[2] );
		return 0;
	case CG_S_CLEARLOOPINGSOUNDS:
		S_ClearLoopingSounds(args[1]);
		return 0;
	case CG_S_ADDLOOPINGSOUND:
		S_AddLoopingSound( args[1], VMA(2), VMA(3), args[4] );
		return 0;
	case CG_S_ADDREALLOOPINGSOUND:
		S_AddRealLoopingSound( args[1], VMA(2), VMA(3), args[4] );
		return 0;
	case CG_S_STOPLOOPINGSOUND:
		S_StopLoopingSound( args[1] );
		return 0;
	case CG_S_UPDATEENTITYPOSITION:
		S_UpdateEntityPosition( args[1], VMA(2) );
		return 0;
	case CG_S_RESPATIALIZE:
		S_Respatialize( args[1], VMA(2), VMA(3), args[4] );
		return 0;
	case CG_S_REGISTERSOUND:
		return S_RegisterSound( VMA(1), args[2] );
	case CG_S_STARTBACKGROUNDTRACK:
		S_StartBackgroundTrack( VMA(1), VMA(2) );
		return 0;
	case CG_R_LOADWORLDMAP:
		CL_R_LoadWorld( VMA( 1 ) );
		return 0; 
	case CG_R_REGISTERMODEL:
		return re.RegisterModel( VMA(1) );
	case CG_R_REGISTERSKIN:
		return re.RegisterSkin( VMA(1) );
	case CG_R_REGISTERSHADER:
		return re.RegisterShader( VMA(1) );
	case CG_R_REGISTERSHADERNOMIP:
		return re.RegisterShaderNoMip( VMA(1) );

	case CG_R_REGISTERFONT:
		return re.RegisterFont( VMA(1) );
	case CG_R_CLEARSCENE:
		re.ClearScene();
		return 0;

	case CG_R_BUILDPOSE:
		{
			animGroupTransition_t trans;
			trans.animGroup = 0;
			trans.interp = 0;
		
			return re.BuildPose( args[1], VMA( 2 ), args[3], VMA( 4 ), args[5], NULL, 0, NULL, 0, &trans, 1 );
		}
	
	case CG_R_BUILDPOSE2:
		return re.BuildPose( args[1], VMA( 2 ), 2, VMA( 3 ), 2, VMA( 4 ), 2, VMA( 5 ), 2, VMA( 6 ), 2 );

	case CG_R_BUILDPOSE3:
		return re.BuildPose( args[1], VMA( 2 ), 1, 0, 0, VMA( 3 ), 1, 0, 0, VMA( 4 ), 1 );

	case CG_R_LERPTAGFROMPOSE:
		return re.LerpTagFromPose( VMA( 1 ), args[2], args[3], VMA( 4 ) );
	
	case CG_R_ADDREFENTITYTOSCENE:
		re.AddRefEntityToScene( VMA(1) );
		return 0;
	case CG_R_ADDPOLYTOSCENE:
		re.AddPolyToScene( args[1], args[2], VMA(3), 1 );
		return 0;
	case CG_R_ADDPOLYSTOSCENE:
		re.AddPolyToScene( args[1], args[2], VMA(3), args[4] );
		return 0;

	case CG_R_MENUBEGINSURF:
		re.MenuBeginSurf( args[1] );
		return 0;

	case CG_R_MENUENDSURF:
		re.MenuEndSurf();
		return 0;

	case CG_R_LIGHTFORPOINT:
		return re.LightForPoint( VMA(1), VMA(2), VMA(3), VMA(4) );
	case CG_R_ADDLIGHTTOSCENE:
		re.AddLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
		return 0;
	case CG_R_ADDADDITIVELIGHTTOSCENE:
		re.AddAdditiveLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
		return 0;
	case CG_R_RENDERSCENE:
		re.RenderScene( VMA(1) );
		return 0;
	case CG_R_SETCOLOR:
		re.SetColor( VMA(1) );
		return 0;
	case CG_R_DRAWSTRETCHPIC:
		re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), NULL, VMF(5), VMF(6), VMF(7), VMF(8), args[9] );
		return 0;
	case CG_R_SHAPECREATE:
		{
			curve_t *	c = VMA(1);
			int			n = args[3];
			int			i;
			for ( i=0; i<n; i++ ) {
				c->pts = (vec2_t*)VM_ArgPtr((intptr_t)c->pts);
				c->uvs = (vec2_t*)VM_ArgPtr((intptr_t)c->uvs);
				c->colors = (vec4_t*)VM_ArgPtr((intptr_t)c->colors);
				c->indices = (short*)VM_ArgPtr((intptr_t)c->indices );
			}
			return re.ShapeCreate( c, VMA( 2 ), n );
		}
	case CG_R_SHAPEDRAW:
		re.ShapeDraw( args[1], args[2], VMA( 3 ) );
		return 0;
	case CG_R_RENDERTEXT:
		CL_RenderText( VMA(1), VMF(2), VMA(3), VMA(4), args[5], (args[6])>>16, args[6]&0xFFFF, args[7], args[8], 0, args[9], VMA(10) );
		return 0;
	case CG_R_GETFONT:
		memcpy( VMA(3), re.GetFontFromFontSet( args[1], VMF(2) ), sizeof(fontInfo_t) );
		return 0;
	case CG_R_ROUNDRECT:
		SCR_FillRect( VMF(1), VMF(2), VMF(3), VMF(4), VMA(5), args[6] );
		return 0;
	case CG_R_MODELBOUNDS:
		re.ModelBounds( args[1], VMA(2), VMA(3) );
		return 0;
	case CG_R_LERPTAG:
		return re.LerpTag( VMA(1), args[2], args[3], args[4], VMF(5), VMA(6) );
	case CG_GETGLCONFIG:
		CL_GetGlconfig( VMA(1) );
		return 0;
	case CG_GETGAMESTATE:
		CL_GetGameState( VMA(1) );
		return 0;
	case CG_GETCURRENTSNAPSHOTNUMBER:
		CL_GetCurrentSnapshotNumber( VMA(1), VMA(2) );
		return 0;
	case CG_GETSNAPSHOT:
		return CL_GetSnapshot( args[1], VMA(2) );
	case CG_GETSERVERCOMMAND:
		return CL_GetServerCommand( args[1] );
	case CG_GETCURRENTCMDNUMBER:
		return CL_GetCurrentCmdNumber();
	case CG_GETUSERCMD:
		return CL_GetUserCmd( args[1], VMA(2) );
	case CG_SETUSERCMDVALUE:
		CL_SetUserCmdValue( args[1], VMF(2) );
		return 0;
	case CG_MEMORY_REMAINING:
		return Hunk_MemoryRemaining();
  case CG_KEY_ISDOWN:
		return Key_IsDown( args[1] );
  case CG_KEY_GETCATCHER:
		return Key_GetCatcher();
  case CG_KEY_SETCATCHER:
		Key_SetCatcher( args[1] );
    return 0;
  case CG_KEY_GETKEY:
		return Key_GetKey( VMA(1) );



	case CG_MEMSET:
		Com_Memset( VMA(1), args[2], args[3] );
		return 0;
	case CG_MEMCPY:
		Com_Memcpy( VMA(1), VMA(2), args[3] );
		return 0;
	case CG_STRNCPY:
		strncpy( VMA(1), VMA(2), args[3] );
		return args[1];
	case CG_SIN:
		return FloatAsInt( sin( VMF(1) ) );
	case CG_COS:
		return FloatAsInt( cos( VMF(1) ) );
	case CG_ATAN2:
		return FloatAsInt( atan2( VMF(1), VMF(2) ) );
	case CG_SQRT:
		return FloatAsInt( sqrt( VMF(1) ) );
	case CG_FLOOR:
		return FloatAsInt( floor( VMF(1) ) );
	case CG_CEIL:
		return FloatAsInt( ceil( VMF(1) ) );
	case CG_ACOS:	return FloatAsInt( Q_acos( VMF(1) ) );
	case CG_FMOD:	return FloatAsInt( fmod( VMF(1),VMF(2) ) );
	case CG_POW:	return FloatAsInt( pow( VMF(1),VMF(2) ) );
	case CG_ATAN:	return FloatAsInt( atan( VMF(1) ) );
	case CG_TAN:	return FloatAsInt( tan( VMF(1)) );

	case CG_PC_ADD_GLOBAL_DEFINE:
		return botlib_export->PC_AddGlobalDefine( VMA(1) );
	case CG_PC_LOAD_SOURCE:
		return botlib_export->PC_LoadSourceHandle( VMA(1) );
	case CG_PC_FREE_SOURCE:
		return botlib_export->PC_FreeSourceHandle( args[1] );
	case CG_PC_READ_TOKEN:
		return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) );
	case CG_PC_SOURCE_FILE_AND_LINE:
		return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) );

	case CG_S_STOPBACKGROUNDTRACK:
		S_StopBackgroundTrack();
		return 0;

	case CG_REAL_TIME:
		return Com_RealTime( VMA(1) );
	case CG_SNAPVECTOR:
		Sys_SnapVector( VMA(1) );
		return 0;

	case CG_UPDATEGAMESTATE:
		return CL_UpdateGameState( VMA(1) );

	case CG_CIN_PLAYCINEMATIC:
	  return CIN_PlayCinematic(VMA(1), args[2], args[3], args[4], args[5], args[6]);

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

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

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

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

	case CG_R_REMAP_SHADER:
		//ToDo: remove this trap
		return 0;

/*
	case CG_LOADCAMERA:
		return loadCamera(VMA(1));

	case CG_STARTCAMERA:
		startCamera(args[1]);
		return 0;

	case CG_GETCAMERAINFO:
		return getCameraInfo(args[1], VMA(2), VMA(3));
*/
	case CG_GET_ENTITY_TOKEN:
		return re.GetEntityToken( VMA(1), args[2] );
	case CG_R_INPVS:
		return re.inPVS( VMA(1), VMA(2) );


	case CG_Q_rand:
		return Rand_NextUInt32( &cl.db.rand );


	case CG_SQL_LOADDB:
		{
			char *	buffer;
			int		length;
			length = FS_ReadFile( VMA(1), &buffer );
			if ( length > 0 ) {
				sql_exec( &cl.db, buffer );
				FS_FreeFile(buffer);
			}
			return 0;
		} break;
	case CG_SQL_EXEC:		return sql_exec( &cl.db, VMA(1) );
	case CG_SQL_PREPARE:	return sql_prepare( &cl.db, VMA(1) ) != 0;
	case CG_SQL_BIND:		return sql_bind( &cl.db, args );
	case CG_SQL_BINDTEXT:	return sql_bindtext( &cl.db, args[1], VMA(2) );
	case CG_SQL_BINDINT:	return sql_bindint( &cl.db, args[1], args[2] );
	case CG_SQL_BINDARGS:
		{
			int i,n = Cmd_Argc();
			for ( i=1; i<n; i++ )
			{
				if ( !sql_bindtext( &cl.db, i, Cmd_Argv( i ) ) )
					return 0;
			}
			
		} return 1;

	case CG_SQL_STEP:			return sql_step( &cl.db );
	case CG_SQL_COLUMNCOUNT:	return sql_columncount( &cl.db );
	case CG_SQL_COLUMNASTEXT:
		Q_strncpyz( VMA(1), sql_columnastext( &cl.db, args[3] ), args[2] );
		break;
	case CG_SQL_COLUMNASINT:	return sql_columnasint( &cl.db, args[1] );
	case CG_SQL_COLUMNNAME:
		Q_strncpyz( VMA(1), sql_columnname( &cl.db, args[3] ), args[2] );
		break;
	case CG_SQL_DONE:			return sql_done( &cl.db );
	case CG_SQL_COMPILE:		return sql_compile( &cl.db, VMA(1) );
	case CG_SQL_RUN:
		{
			char *	buffer	= VMA(1);
			int		size	= args[2];
			int		id		= args[3];
			int		i;
			formatInfo_t *	stmt = (formatInfo_t*)cl.db.stmts_byindex[ id ];

			if ( stmt ) {

				sqlData_t params[ 3 ];
				const char * r;

				for ( i=0; i<3; i++ ) {

					params[ i ].format = INTEGER;
					params[ i ].payload.integer = args[ 4+i ];
				}

				r = sql_eval( &cl.db, stmt->print, 0, 0, 0, 0, params, 0 ).string;

				Q_strncpyz( buffer, r, size );
			} else {
				buffer[ 0 ] = '\0';
			}

		} break;

	default:
	        assert(0); // bk010102
		Com_Error( ERR_DROP, "Bad cgame system trap: %i", args[0] );
	}
	return 0;
}
Beispiel #28
0
// Do very shallow parse of the demo (could be extended) just to get times and snapshot count
static void CL_ParseDemo(void)
{
	int tstart   = 0;
	int demofile = 0;

	// Reset our demo data
	memset(&di, 0, sizeof(di));

	// Parse start
	di.gameStartTime = -1;
	di.gameEndTime   = -1;
	FS_Seek(clc.demofile, 0, FS_SEEK_SET);
	tstart = Sys_Milliseconds();

	while (qtrue)
	{
		int   r;
		msg_t buf;
		msg_t *msg;
		byte  bufData[MAX_MSGLEN];
		int   s;
		int   cmd;

		di.demoPos = FS_FTell(clc.demofile);

		// get the sequence number
		r = FS_Read(&s, 4, clc.demofile);
		if (r != 4)
		{
			CL_DemoCompleted();
			return;
		}

		clc.serverMessageSequence = LittleLong(s);

		// init the message
		MSG_Init(&buf, bufData, sizeof(bufData));

		// get the length
		r = FS_Read(&buf.cursize, 4, clc.demofile);

		if (r != 4)
		{
			break;
		}

		buf.cursize = LittleLong(buf.cursize);
		if (buf.cursize == -1)
		{
			break;
		}

		if (buf.cursize > buf.maxsize)
		{
			Com_FuncDPrinf("demoMsglen > MAX_MSGLEN");
			break;
		}

		r = FS_Read(buf.data, buf.cursize, clc.demofile);
		if (r != buf.cursize)
		{
			Com_FuncDPrinf("Demo file was truncated.\n");
			break;
		}

		clc.lastPacketTime = cls.realtime;
		buf.readcount      = 0;

		// parse
		msg = &buf;
		MSG_Bitstream(msg);

		// get the reliable sequence acknowledge number
		clc.reliableAcknowledge = MSG_ReadLong(msg);

		if (clc.reliableAcknowledge < clc.reliableSequence - MAX_RELIABLE_COMMANDS)
		{
			clc.reliableAcknowledge = clc.reliableSequence;
		}

		// parse the message
		while (qtrue)
		{
			if (msg->readcount > msg->cursize)
			{
				Com_FuncDrop("read past end of server message");
				break;
			}

			cmd = MSG_ReadByte(msg);

			if (cmd == svc_EOF)
			{
				break;
			}

			// other commands
			switch (cmd)
			{
			default:
				Com_FuncDrop("Illegible server message %d", cmd);
				break;
			case svc_nop:
				break;
			case svc_serverCommand:
				MSG_ReadLong(msg);
				MSG_ReadString(msg);
				break;
			case svc_gamestate:
				clc.serverCommandSequence = MSG_ReadLong(msg);
				cl.gameState.dataCount    = 1;
				while (qtrue)
				{
					int cmd2 = MSG_ReadByte(msg);
					if (cmd2 == svc_EOF)
					{
						break;
					}
					if (cmd2 == svc_configstring)
					{
						MSG_ReadShort(msg);
						MSG_ReadBigString(msg);
					}
					else if (cmd2 == svc_baseline)
					{
						entityState_t s1, s2;
						memset(&s1, 0, sizeof(s1));
						memset(&s2, 0, sizeof(s2));
						MSG_ReadBits(msg, GENTITYNUM_BITS);
						MSG_ReadDeltaEntity(msg, &s1, &s2, 0);
					}
					else
					{
						Com_FuncDrop("bad command byte");
					}
				}
				MSG_ReadLong(msg);
				MSG_ReadLong(msg);
				break;
			case svc_snapshot:
				CL_ParseDemoSnapShotSimple(msg);
				break;
			case svc_download:
				MSG_ReadShort(msg);

				break;
			}
		}

		if (!cl.snap.valid)
		{
			Com_FuncDPrinf("!cl.snap.valid\n");
			continue;
		}

		if (cl.snap.serverTime < cl.oldFrameServerTime)
		{
			// ignore snapshots that don't have entities
			if (cl.snap.snapFlags & SNAPFLAG_NOT_ACTIVE)
			{
				continue;
			}
			cls.state = CA_ACTIVE;

			// set the timedelta so we are exactly on this first frame
			cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
			cl.oldServerTime   = cl.snap.serverTime;

			clc.timeDemoBaseTime = cl.snap.serverTime;
		}
		cl.oldFrameServerTime = cl.snap.serverTime;

		if (cl.newSnapshots)
		{
			CL_AdjustTimeDelta();
		}

		di.lastServerTime = cl.snap.serverTime;
		if (di.firstServerTime == 0)
		{
			di.firstServerTime = cl.snap.serverTime;
			Com_FuncPrinf("firstServerTime %d\n", di.firstServerTime);
		}

		di.snapsInDemo++;
	}

	Com_FuncDPrinf("Snaps in demo: %i\n", di.snapsInDemo);
	Com_FuncDPrinf("last serverTime %d   total %f minutes\n", cl.snap.serverTime, (cl.snap.serverTime - di.firstServerTime) / 1000.0 / 60.0);
	Com_FuncDPrinf("parse time %f seconds\n", (float)(Sys_Milliseconds() - tstart) / 1000.0);
	FS_Seek(clc.demofile, 0, FS_SEEK_SET);
	clc.demoplaying = qfalse;
	demofile        = clc.demofile;
	CL_ClearState();
	Com_Memset(&clc, 0, sizeof(clc));
	clc.demofile             = demofile;
	cls.state                = CA_DISCONNECTED;
	cl_connectedToPureServer = qfalse;

	dpi.firstTime = di.firstServerTime;
	dpi.lastTime  = di.lastServerTime;
}
Beispiel #29
0
/*
==================
SV_WriteDownloadToClient

Check to see if the client wants a file, open it if needed and start pumping the client
Fill up msg with data 
==================
*/
void SV_WriteDownloadToClient(client_t *cl, msg_t *msg)
{
	int curindex;
	int rate;
	int blockspersnap;
	int unreferenced = 1;
	char errorMessage[1024];
	char pakbuf[MAX_QPATH], *pakptr;
	int numRefPaks;

	if (!*cl->downloadName)
		return;	// Nothing being downloaded

	if(!cl->download)
	{
		qboolean idPack = qfalse;
		qboolean missionPack = qfalse;
	
 		// Chop off filename extension.
		Com_sprintf(pakbuf, sizeof(pakbuf), "%s", cl->downloadName);
		pakptr = strrchr(pakbuf, '.');
		
		if(pakptr)
		{
			*pakptr = '\0';

			// Check for pk3 filename extension
			if(!Q_stricmp(pakptr + 1, "pk3"))
			{
				const char *referencedPaks = FS_ReferencedPakNames();

				// Check whether the file appears in the list of referenced
				// paks to prevent downloading of arbitrary files.
				Cmd_TokenizeStringIgnoreQuotes(referencedPaks);
				numRefPaks = Cmd_Argc();

				for(curindex = 0; curindex < numRefPaks; curindex++)
				{
					if(!FS_FilenameCompare(Cmd_Argv(curindex), pakbuf))
					{
						unreferenced = 0;

						// now that we know the file is referenced,
						// check whether it's legal to download it.
						missionPack = FS_idPak(pakbuf, "missionpack");
						idPack = missionPack;
						idPack = (qboolean)(idPack || FS_idPak(pakbuf, "base"));

						break;
					}
				}
			}
		}

		cl->download = 0;

		// We open the file here
		if ( !sv_allowDownload->integer ||
			idPack || unreferenced ||
			( cl->downloadSize = FS_SV_FOpenFileRead( cl->downloadName, &cl->download ) ) < 0 ) {
			// cannot auto-download file
			if(unreferenced)
			{
				Com_Printf("clientDownload: %d : \"%s\" is not referenced and cannot be downloaded.\n", (int) (cl - svs.clients), cl->downloadName);
				Com_sprintf(errorMessage, sizeof(errorMessage), "File \"%s\" is not referenced and cannot be downloaded.", cl->downloadName);
			}
			else if (idPack) {
				Com_Printf("clientDownload: %d : \"%s\" cannot download id pk3 files\n", (int) (cl - svs.clients), cl->downloadName);
				if(missionPack)
				{
					Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload Team Arena file \"%s\"\n"
									"The Team Arena mission pack can be found in your local game store.", cl->downloadName);
				}
				else
				{
					Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload id pk3 file \"%s\"", cl->downloadName);
				}
			}
			else if ( !sv_allowDownload->integer ) {
				Com_Printf("clientDownload: %d : \"%s\" download disabled\n", (int) (cl - svs.clients), cl->downloadName);
				if (sv_pure->integer) {
					Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n"
										"You will need to get this file elsewhere before you "
										"can connect to this pure server.\n", cl->downloadName);
				} else {
					Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n"
                    "The server you are connecting to is not a pure server, "
                    "set autodownload to No in your settings and you might be "
                    "able to join the game anyway.\n", cl->downloadName);
				}
			} else {
        // NOTE TTimo this is NOT supposed to happen unless bug in our filesystem scheme?
        //   if the pk3 is referenced, it must have been found somewhere in the filesystem
				Com_Printf("clientDownload: %d : \"%s\" file not found on server\n", (int) (cl - svs.clients), cl->downloadName);
				Com_sprintf(errorMessage, sizeof(errorMessage), "File \"%s\" not found on server for autodownloading.\n", cl->downloadName);
			}
			MSG_WriteByte( msg, svc_download );
			MSG_WriteShort( msg, 0 ); // client is expecting block zero
			MSG_WriteLong( msg, -1 ); // illegal file size
			MSG_WriteString( msg, errorMessage );

			*cl->downloadName = 0;
			
			if(cl->download)
				FS_FCloseFile(cl->download);
			
			return;
		}
 
		Com_Printf( "clientDownload: %d : beginning \"%s\"\n", (int) (cl - svs.clients), cl->downloadName );
		
		// Init
		cl->downloadCurrentBlock = cl->downloadClientBlock = cl->downloadXmitBlock = 0;
		cl->downloadCount = 0;
		cl->downloadEOF = qfalse;
	}

	// Perform any reads that we need to
	while (cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW &&
		cl->downloadSize != cl->downloadCount) {

		curindex = (cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW);

		if (!cl->downloadBlocks[curindex])
			cl->downloadBlocks[curindex] = (unsigned char *)Z_Malloc( MAX_DOWNLOAD_BLKSIZE, TAG_DOWNLOAD, qtrue );

		cl->downloadBlockSize[curindex] = FS_Read( cl->downloadBlocks[curindex], MAX_DOWNLOAD_BLKSIZE, cl->download );

		if (cl->downloadBlockSize[curindex] < 0) {
			// EOF right now
			cl->downloadCount = cl->downloadSize;
			break;
		}

		cl->downloadCount += cl->downloadBlockSize[curindex];

		// Load in next block
		cl->downloadCurrentBlock++;
	}

	// Check to see if we have eof condition and add the EOF block
	if (cl->downloadCount == cl->downloadSize &&
		!cl->downloadEOF &&
		cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW) {

		cl->downloadBlockSize[cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW] = 0;
		cl->downloadCurrentBlock++;

		cl->downloadEOF = qtrue;  // We have added the EOF block
	}

	// Loop up to window size times based on how many blocks we can fit in the
	// client snapMsec and rate

	// based on the rate, how many bytes can we fit in the snapMsec time of the client
	// normal rate / snapshotMsec calculation
	rate = cl->rate;
	if ( sv_maxRate->integer ) {
		if ( sv_maxRate->integer < 1000 ) {
			Cvar_Set( "sv_MaxRate", "1000" );
		}
		if ( sv_maxRate->integer < rate ) {
			rate = sv_maxRate->integer;
		}
	}

	if (!rate) {
		blockspersnap = 1;
	} else {
		blockspersnap = ( (rate * cl->snapshotMsec) / 1000 + MAX_DOWNLOAD_BLKSIZE ) /
			MAX_DOWNLOAD_BLKSIZE;
	}

	if (blockspersnap < 0)
		blockspersnap = 1;

	while (blockspersnap--) {

		// Write out the next section of the file, if we have already reached our window,
		// automatically start retransmitting

		if (cl->downloadClientBlock == cl->downloadCurrentBlock)
			return; // Nothing to transmit

		if (cl->downloadXmitBlock == cl->downloadCurrentBlock) {
			// We have transmitted the complete window, should we start resending?

			//FIXME:  This uses a hardcoded one second timeout for lost blocks
			//the timeout should be based on client rate somehow
			if (svs.time - cl->downloadSendTime > 1000)
				cl->downloadXmitBlock = cl->downloadClientBlock;
			else
				return;
		}

		// Send current block
		curindex = (cl->downloadXmitBlock % MAX_DOWNLOAD_WINDOW);

		MSG_WriteByte( msg, svc_download );
		MSG_WriteShort( msg, cl->downloadXmitBlock );

		// block zero is special, contains file size
		if ( cl->downloadXmitBlock == 0 )
			MSG_WriteLong( msg, cl->downloadSize );
 
		MSG_WriteShort( msg, cl->downloadBlockSize[curindex] );

		// Write the block
		if ( cl->downloadBlockSize[curindex] ) {
			MSG_WriteData( msg, cl->downloadBlocks[curindex], cl->downloadBlockSize[curindex] );
		}

		Com_DPrintf( "clientDownload: %d : writing block %d\n", cl - svs.clients, cl->downloadXmitBlock );

		// Move on to the next block
		// It will get sent with next snap shot.  The rate will keep us in line.
		cl->downloadXmitBlock++;

		cl->downloadSendTime = svs.time;
	}
}
Beispiel #30
0
/* <65b51> ../engine/net_chan.c:412 */
void Netchan_Transmit(netchan_t *chan, int length, byte *data)
{
	byte		send_buf[NET_MAX_MESSAGE];
	qboolean	send_reliable;
	qboolean	send_reliable_fragment;
	qboolean	send_resending = false;
	unsigned	w1, w2;
	int i, j;

	float       fRate;

	sizebuf_t sb_send;
	sb_send.data = send_buf;
	sb_send.buffername = "Netchan_Transmit";
	sb_send.maxsize = sizeof(send_buf);
	sb_send.flags = 0;
	sb_send.cursize = 0;

	// check for message overflow
	if (chan->message.flags & 2) {
		Con_Printf("%s:Outgoing message overflow\n", NET_AdrToString(chan->remote_address));
		return;
	}

	// if the remote side dropped the last reliable message, resend it
	send_reliable = false;

	if (chan->incoming_acknowledged > chan->last_reliable_sequence &&
		chan->incoming_reliable_acknowledged != chan->reliable_sequence)
	{
		send_reliable = true;
		send_resending = true;
	}

	//
	// A packet can have "reliable payload + frag payload + unreliable payload
	// frag payload can be a file chunk, if so, it needs to be parsed on the receiving end and reliable payload + unreliable payload need
	// to be passed on to the message queue.  The processing routine needs to be able to handle the case where a message comes in and a file
	// transfer completes
	//
	//
	// if the reliable transmit buffer is empty, copy the current message out
	if (!chan->reliable_length)
	{
		qboolean send_frag = false;
		fragbuf_t *pbuf;

		// Will be true if we are active and should let chan->message get some bandwidth
		int		 send_from_frag[MAX_STREAMS] = { 0, 0 };
		int		 send_from_regular = 0;

		// If we have data in the waiting list(s) and we have cleared the current queue(s), then 
		//  push the waitlist(s) into the current queue(s)
		Netchan_FragSend(chan);

		// Sending regular payload
		send_from_regular = (chan->message.cursize) ? 1 : 0;

		// Check to see if we are sending a frag payload
		//
		for (i = 0; i < MAX_STREAMS; i++)
		{
			if (chan->fragbufs[i])
			{
				send_from_frag[i] = 1;
			}
		}

		// Stall reliable payloads if sending from frag buffer
		if (send_from_regular && (send_from_frag[FRAG_NORMAL_STREAM]))
		{
			send_from_regular = false;

			// If the reliable buffer has gotten too big, queue it at the end of everything and clear out buffer
			//
			if (chan->message.cursize > MAX_RELIABLE_PAYLOAD)
			{
				Netchan_CreateFragments_(chan == &g_pcls.netchan ? 1 : 0, chan, &chan->message);
				SZ_Clear(&chan->message);
			}
		}

		// Startpos will be zero if there is no regular payload
		for (i = 0; i < MAX_STREAMS; i++)
		{
			chan->frag_startpos[i] = 0;

			// Assume no fragment is being sent
			chan->reliable_fragment[i] = 0;
			chan->reliable_fragid[i] = 0;
			chan->frag_length[i] = 0;

			if (send_from_frag[i])
			{
				send_frag = true;
			}
		}

		if (send_from_regular || send_frag)
		{
			chan->reliable_sequence ^= 1;
			send_reliable = true;
		}

		if (send_from_regular) {
			Q_memcpy(chan->reliable_buf, chan->message_buf, chan->message.cursize);
			chan->reliable_length = chan->message.cursize;
			SZ_Clear(&chan->message);

			// If we send fragments, this is where they'll start
			for (i = 0; i < MAX_STREAMS; i++) {
				chan->frag_startpos[i] = chan->reliable_length;
			}
		}

		for (i = 0; i < MAX_STREAMS; i++) {
			int fragment_size;

			// Is there something in the fragbuf?
			pbuf = chan->fragbufs[i];

			fragment_size = 0; // Compiler warning.
			if (pbuf)	{
				fragment_size = pbuf->frag_message.cursize;

				// Files set size a bit differently.
				if (pbuf->isfile && !pbuf->isbuffer)
				{
					fragment_size = pbuf->size;
				}
			}

			// Make sure we have enought space left
			if (send_from_frag[i] && pbuf && ((chan->reliable_length + fragment_size) < MAX_RELIABLE_PAYLOAD)) {

				chan->reliable_fragid[i] = MAKE_FRAGID(pbuf->bufferid, chan->fragbufcount[i]); // Which buffer are we sending?

				// If it's not in-memory, then we'll need to copy it in frame the file handle.
				if (pbuf->isfile && !pbuf->isbuffer)	{
					char compressedfilename[MAX_PATH];
					FileHandle_t hfile;
					if (pbuf->iscompressed)
					{
						Q_snprintf(compressedfilename, sizeof(compressedfilename), "%s.ztmp", pbuf->filename);
						hfile = FS_Open(compressedfilename, "rb");
					}
					else
					{
						hfile = FS_Open(pbuf->filename, "rb");
					}
					FS_Seek(hfile, pbuf->foffset, FILESYSTEM_SEEK_HEAD);
					FS_Read(&pbuf->frag_message.data[pbuf->frag_message.cursize], pbuf->size, 1, hfile);
					pbuf->frag_message.cursize += pbuf->size;
					FS_Close(hfile);
				}


				Q_memcpy(chan->reliable_buf + chan->reliable_length, pbuf->frag_message.data, pbuf->frag_message.cursize);
				chan->reliable_length += pbuf->frag_message.cursize;
				chan->frag_length[i] = pbuf->frag_message.cursize;


				// Unlink  pbuf
				Netchan_UnlinkFragment(pbuf, &chan->fragbufs[i]);

				chan->reliable_fragment[i] = 1;

				// Offset the rest of the starting positions
				for (j = i + 1; j < MAX_STREAMS; j++)
				{
					chan->frag_startpos[j] += chan->frag_length[i];
				}
			}
		}
	}

	// Prepare the packet header
	w1 = chan->outgoing_sequence | (send_reliable << 31);
	w2 = chan->incoming_sequence | (chan->incoming_reliable_sequence << 31);

	send_reliable_fragment = false;

	for (i = 0; i < MAX_STREAMS; i++)
	{
		if (chan->reliable_fragment[i])
		{
			send_reliable_fragment = true;
			break;
		}
	}

	if (send_reliable && send_reliable_fragment)
	{
		w1 |= (1 << 30);
	}

	chan->outgoing_sequence++;

	MSG_WriteLong(&sb_send, w1);
	MSG_WriteLong(&sb_send, w2);

	if (send_reliable && send_reliable_fragment)
	{
		for (i = 0; i < MAX_STREAMS; i++)
		{
			if (chan->reliable_fragment[i])
			{
				MSG_WriteByte(&sb_send, 1);
				MSG_WriteLong(&sb_send, chan->reliable_fragid[i]);
				MSG_WriteShort(&sb_send, chan->frag_startpos[i]);
				MSG_WriteShort(&sb_send, chan->frag_length[i]);
			}
			else
			{
				MSG_WriteByte(&sb_send, 0);
			}
		}
	}

	// Copy the reliable message to the packet first
	if (send_reliable) {
		SZ_Write(&sb_send, chan->reliable_buf, chan->reliable_length);
		chan->last_reliable_sequence = chan->outgoing_sequence - 1;
	}

	// Is there room for the unreliable payload?
	int max_send_size = MAX_ROUTEABLE_PACKET;
	if (!send_resending)
		max_send_size = sb_send.maxsize;

	if ((max_send_size - sb_send.cursize) >= length) {
		SZ_Write(&sb_send, data, length);
	}
	else {
		Con_DPrintf("Netchan_Transmit:  Unreliable would overfow, ignoring\n");
	}

	// Deal with packets that are too small for some networks
	if (sb_send.cursize < 16)	// Packet too small for some networks
	{
		int i;
		// Go ahead and pad a full 16 extra bytes -- this only happens during authentication / signon
		for (i = sb_send.cursize; i < 16; i++)
		{
			// Note that the server can parse svc_nop, too.
			MSG_WriteByte(&sb_send, svc_nop);
		}
	}

	int statId = chan->flow[FLOW_OUTGOING].current & 0x1F;
	chan->flow[FLOW_OUTGOING].stats[statId].size = sb_send.cursize + UDP_HEADER_SIZE;
	chan->flow[FLOW_OUTGOING].stats[statId].time = realtime;
	chan->flow[FLOW_OUTGOING].current++;
	Netchan_UpdateFlow(chan);

	if (!g_pcls.demoplayback)
	{
		COM_Munge2(sb_send.data + 8, sb_send.cursize - 8, (unsigned char)(chan->outgoing_sequence - 1));

		if (g_modfuncs.m_pfnProcessOutgoingNet)
			g_modfuncs.m_pfnProcessOutgoingNet(chan, &sb_send);

		NET_SendPacket(chan->sock, sb_send.cursize, sb_send.data, chan->remote_address);
	}

	if (g_psv.active && sv_lan.value != 0.0f && sv_lan_rate.value > MIN_RATE)
		fRate = 1.0 / sv_lan_rate.value;
	else
		fRate = 1.0 / chan->rate;

	if (chan->cleartime < realtime) {
		chan->cleartime = realtime;
	}

	chan->cleartime += (sb_send.cursize + UDP_HEADER_SIZE) * fRate;

	if (net_showpackets.value != 0.0f && net_showpackets.value != 2.0f) {
		char c = (chan == &g_pcls.netchan) ? 'c' : 's';

		Con_Printf(" %c --> sz=%i seq=%i ack=%i rel=%i tm=%f\n"
				   , c
				   , sb_send.cursize
				   , chan->outgoing_sequence - 1
				   , chan->incoming_sequence
				   , send_reliable ? 1 : 0
				   , (float)(chan == &g_pcls.netchan ? g_pcl.time : g_psv.time));
	}
}