/*
========================
CG_ReadNextSnapshot

This is the only place new snapshots are requested
This may increment cgs.processedSnapshotNum multiple
times if the client system fails to return a
valid snapshot.
========================
*/
static snapshot_t *CG_ReadNextSnapshot( void ) {
	qboolean	r;
	snapshot_t	*dest;

	if ( cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000 ) {
		CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i", 
			cg.latestSnapshotNum, cgs.processedSnapshotNum );
	}

	while ( cgs.processedSnapshotNum < cg.latestSnapshotNum ) {
		// decide which of the two slots to load it into
		if ( cg.snap == &cg.activeSnapshots[0] ) {
			dest = &cg.activeSnapshots[1];
		} else {
			dest = &cg.activeSnapshots[0];
		}

		// try to read the snapshot from the client system
		cgs.processedSnapshotNum++;
		r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );

		// FIXME: why would trap_GetSnapshot return a snapshot with the same server time
		if ( cg.snap && r && dest->serverTime == cg.snap->serverTime ) {
			//continue;
		}

		// if it succeeded, return
		if ( r ) {
			CG_AddLagometerSnapshotInfo( dest );
			return dest;
		}

		// a GetSnapshot will return failure if the snapshot
		// never arrived, or  is so old that its entities
		// have been shoved off the end of the circular
		// buffer in the client system.

		// record as a dropped packet
		CG_AddLagometerSnapshotInfo( NULL );

		// If there are additional snapshots, continue trying to
		// read them.
	}

	// nothing left to read
	return NULL;
}
Example #2
0
/*
========================
CG_ReadNextSnapshot

This is the only place new snapshots are requested
This may increment cgs.processedSnapshotNum multiple
times if the client system fails to return a
valid snapshot.
========================
*/
static snapshot_t *CG_ReadNextSnapshot( void ) {
	qboolean	r;
	snapshot_t	*dest;

	if ( cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000 ) {
		CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i\n", 
			cg.latestSnapshotNum, cgs.processedSnapshotNum );
	}

	while ( cgs.processedSnapshotNum < cg.latestSnapshotNum ) {
		// decide which of the two slots to load it into
		if ( cg.snap == &cg.activeSnapshots[0] ) {
			dest = &cg.activeSnapshots[1];
		} else {
			dest = &cg.activeSnapshots[0];
		}

		// try to read the snapshot from the client system
		cgs.processedSnapshotNum++;
		r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );

		// FIXME: why would trap_GetSnapshot return a snapshot with the same server time
		if ( cg.snap && r && dest->serverTime == cg.snap->serverTime ) {
			//continue;
		}

		// if it succeeded, return
		if ( r ) {
			return dest;
		}
		// If there are additional snapshots, continue trying to
		// read them.
	}

	// nothing left to read
	return NULL;
}
/*
========================
CG_ReadNextSnapshot

This is the only place new snapshots are requested
This may increment cgs.processedSnapshotNum multiple
times if the client system fails to return a
valid snapshot.
========================
*/
static snapshot_t *CG_ReadNextSnapshot( void ) {
	qboolean	r;
	snapshot_t	*dest;

	if ( cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000 ) {
		CG_Printf( "[skipnotify]WARNING: CG_ReadNextSnapshot: way out of range, %i > %i\n", 
			cg.latestSnapshotNum, cgs.processedSnapshotNum );
	}

	while ( cgs.processedSnapshotNum < cg.latestSnapshotNum ) {
		// decide which of the two slots to load it into
		if ( cg.snap == &cg.activeSnapshots[0] ) {
			dest = &cg.activeSnapshots[1];
		} else {
			dest = &cg.activeSnapshots[0];
		}

		// try to read the snapshot from the client system
		cgs.processedSnapshotNum++;
		r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );

		// FIXME: why would trap_GetSnapshot return a snapshot with the same server time
		if ( cg.snap && r && dest->serverTime == cg.snap->serverTime ) {
			//continue;
		}

		// if it succeeded, return
		if ( r ) {
			CG_AddLagometerSnapshotInfo( dest );
			// server has been restarted
			if ( cg.snap && ( dest->snapFlags ^ cg.snap->snapFlags ) & SNAPFLAG_SERVERCOUNT ) {
				cg.damageTime = 0;
				cg.duckTime = -1;
				cg.landTime = -1;
				cg.stepTime = -1;
#ifdef SAVEGAME_SUPPORT
				// savegame: we should use this as our new base snapshot
				if( CG_IsSinglePlayer() ) {
					int i;
					centity_t backupCent;
					CG_SetInitialSnapshot( dest );
					cg.nextFrameTeleport = qtrue;
					// loadgame hasn't occured yet, so this is likely wrong
					//cg.weaponSelect = cg.snap->ps.weapon;
					cg.weaponSelectTime = cg.time;
					memset( cg.viewDamage, 0, sizeof(cg.viewDamage) );
				//	memset( cg.cameraShake, 0, sizeof(cg.cameraShake) );
					// go through an reset the cent's
					for (i=0; i<MAX_GENTITIES; i++) {
						backupCent = cg_entities[i];
						memset( &cg_entities[i], 0, sizeof(centity_t) );
						cg_entities[i].currentState = backupCent.currentState;
						cg_entities[i].nextState = backupCent.nextState;
						cg_entities[i].currentValid = backupCent.currentValid;
						cg_entities[i].interpolate = backupCent.interpolate;
					}
					// reset the predicted cent
					memset( &cg.predictedPlayerEntity, 0, sizeof(centity_t) );
					cg.predictedPlayerEntity.currentState = backupCent.currentState;
					cg.predictedPlayerEntity.nextState = backupCent.nextState;
					cg.predictedPlayerEntity.currentValid = backupCent.currentValid;
					cg.predictedPlayerEntity.interpolate = backupCent.interpolate;

					return NULL;
				}
#endif // SAVEGAME_SUPPORT
			}
//
			return dest;
		}

		// a GetSnapshot will return failure if the snapshot
		// never arrived, or  is so old that its entities
		// have been shoved off the end of the circular
		// buffer in the client system.

		// record as a dropped packet
		CG_AddLagometerSnapshotInfo( NULL );

		// If there are additional snapshots, continue trying to
		// read them.
	}

	// nothing left to read
	return NULL;
}
Example #4
0
static snapshot_t *CG_ReadNextSnapshot( void ) {
	qboolean	r;
	snapshot_t	*dest;

	if ( cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000 ) {
		CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i\n",
			cg.latestSnapshotNum, cgs.processedSnapshotNum );
	}

	while ( cgs.processedSnapshotNum < cg.latestSnapshotNum ) {
		// decide which of the two slots to load it into
		if ( cg.snap == &cg.activeSnapshots[0] ) {
			dest = &cg.activeSnapshots[1];
		} else {
			dest = &cg.activeSnapshots[0];
		}

		// try to read the snapshot from the client system
		cgs.processedSnapshotNum++;

		if ( jk2version == VERSION_1_02 )
		{ // MVSDK: Multiversion magic!
			r = trap_GetSnapshot( cgs.processedSnapshotNum, (snapshot_t*)&activeSnapshot_1_02 );
		}
		else
		{
			r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );
		}

		// FIXME: why would trap_GetSnapshot return a snapshot with the same server time
		if ( cg.snap && r && dest->serverTime == cg.snap->serverTime ) {
			//continue;
		}

		// if it succeeded, return
		if ( r ) {
			if ( jk2version == VERSION_1_02 )
			{ // MVSDK: Multiversion Magic
				static const size_t section1 = (size_t)((char *)&((snapshot_t*)NULL)->ps);
				static const size_t section2 = (size_t)((char *)&((playerState_t*)NULL)->forceRestricted);
				static const size_t section3 = (size_t)((char *)&((playerState_t*)NULL)->saberIndex - (char *)&((playerState_t*)NULL)->forceRestricted);
				static const size_t section4 = (size_t)((char *)(&((snapshot_t*)NULL)->ps) + sizeof(playerState_t) - (char *)&((snapshot_t*)NULL)->ps.saberIndex);
				static const size_t section5 = (size_t)((char *)(&(((snapshot_t*)NULL)[1])) - (char *)&((snapshot_t*)NULL)->numEntities);

				/* Convert the snapshot (mainly because of the playerState) */
				memcpy( dest, &(activeSnapshot_1_02), section1 ); // Copy everything till ps
				memcpy( &(dest->ps), &(activeSnapshot_1_02.ps), section2 ); // Copy everything till ps.forceRestricted
				memset( &(dest->ps.forceRestricted), 0, section3 ); // 0 everything from ps.forceRestricted till ps.saberIndex
				memcpy( &(dest->ps.saberIndex), &(activeSnapshot_1_02.ps.saberIndex), section4 ); // Copy everything starting with ps.saberIndex
				memcpy( &dest->numEntities, &(activeSnapshot_1_02.numEntities), section5 ); // Copy everything after ps
			}
			if ( jk2startversion == VERSION_1_02 )
			{
				/* Convert the animations */
				dest->ps.legsAnim = MV_MapAnimation104(dest->ps.legsAnim);
				dest->ps.legsAnimExecute = MV_MapAnimation104(dest->ps.legsAnimExecute);
				dest->ps.torsoAnim = MV_MapAnimation104(dest->ps.torsoAnim);
				dest->ps.torsoAnimExecute = MV_MapAnimation104(dest->ps.torsoAnimExecute);

				/* Only convert forceDodgeAnim if it really is an animation (forceHandExtend being either HANDEXTEND_TAUNT or HANDEXTEND_DODGE) */
				if ( dest->ps.forceHandExtend == HANDEXTEND_TAUNT || dest->ps.forceHandExtend == HANDEXTEND_DODGE ) dest->ps.forceDodgeAnim = MV_MapAnimation104(dest->ps.forceDodgeAnim);

				/* The following two seem to be unused, but maybe custom cgames make use of them (well, fullAnimExecute seems to not even be set at least once - could probably just leave that one out) */
				dest->ps.fullAnimExecute = MV_MapAnimation104(dest->ps.fullAnimExecute);
				dest->ps.saberAttackSequence = MV_MapAnimation104(dest->ps.saberAttackSequence);

				/* Convert the saberblocks */
				if (dest->ps.saberBlocked > BLOCKED_NONE) {
					dest->ps.saberBlocked++;
				}
			}
			CG_AddLagometerSnapshotInfo( dest );
			return dest;
		}

		// a GetSnapshot will return failure if the snapshot
		// never arrived, or  is so old that its entities
		// have been shoved off the end of the circular
		// buffer in the client system.

		// record as a dropped packet
		CG_AddLagometerSnapshotInfo( NULL );

		// If there are additional snapshots, continue trying to
		// read them.
	}

	// nothing left to read
	return NULL;
}