예제 #1
0
void process_action_flags(
	short player_identifier, 
	const uint32 *action_flags, 
	short count)
{
	if (replay.game_is_being_recorded)
	{
		record_action_flags(player_identifier, action_flags, count);
	}
	
	GetRealActionQueues()->enqueueActionFlags(player_identifier, action_flags, count);
}
예제 #2
0
/*********************************************************************************************
 *
 * Function: pull_flags_from_recording
 * Purpose:  remove one flag from each queue from the recording buffer.
 * Returns:  true if it pulled the flags, false if it didn't
 *
 *********************************************************************************************/
static bool pull_flags_from_recording(
	short count)
{
	short player_index;
	bool success= true;
	
	// first check that we can pull something from each playerÕs queue
	// (at the beginning of the game, we wonÕt be able to)
	// i'm not sure that i really need to do this check. oh well.
	for (player_index = 0; success && player_index<dynamic_world->player_count; player_index++)
	{
		if(get_recording_queue_size(player_index)==0) success= false;
	}

	if(success)
	{
		for (player_index = 0; player_index < dynamic_world->player_count; player_index++)
		{
			short index;
			ActionQueue  *queue;
		
			queue= get_player_recording_queue(player_index);
			for (index= 0; index<count; index++)
			{
				if (queue->read_index != queue->write_index)
				{
#ifdef DEBUG_REPLAY
					debug_stream_of_flags(*(queue->buffer+queue->read_index), player_index);
#endif
                    GetRealActionQueues()->enqueueActionFlags(player_index, queue->buffer + queue->read_index, 1);
					INCREMENT_QUEUE_COUNTER(queue->read_index);
				} else {
					dprintf("Dropping flag?");
				}
			}
		}
	}
	
	return success;
}
예제 #3
0
std::pair<bool, int16>
update_world()
{
        short theElapsedTime = 0;
        bool canUpdate = true;
        int theUpdateResult = kUpdateNormalCompletion;

#ifndef DISABLE_NETWORKING
	if (game_is_networked)
		NetProcessMessagesInGame();
#endif
        
        while(canUpdate)
        {
                // If we have flags in the GameQueue, or can put a tick's-worth there, we're ok.
                // Note that GameQueue should be stocked evenly (i.e. every player has the same # of flags)
                if(GameQueue->countActionFlags(0) == 0)
                {
                        canUpdate = overlay_queue_with_queue_into_queue(GetRealActionQueues(), GetLuaActionQueues(), GameQueue);
                }

		if(!sPredictionWanted)
		{
			// See if the speed-limiter (net time or heartbeat count) will let us advance a tick
#if !defined(DISABLE_NETWORKING)
			int theMostRecentAllowedTick = game_is_networked ? NetGetNetTime() : get_heartbeat_count();
#else
			int theMostRecentAllowedTick = get_heartbeat_count();
#endif

			if(dynamic_world->tick_count >= theMostRecentAllowedTick)
			{
				canUpdate = false;
			}
		}
                
                // If we can't update, we can't update.  We're done for now.
                if(!canUpdate)
                {
                        break;
                }

		// Transition from predictive -> real update mode, if necessary.
		exit_predictive_mode();

		// Capture the flags for each player for use in prediction
		for(short i = 0; i < dynamic_world->player_count; i++)
			sMostRecentFlagsForPlayer[i] = GameQueue->peekActionFlags(i, 0);

		theUpdateResult = update_world_elements_one_tick();

                theElapsedTime++;

                
                L_Call_PostIdle();
                if(theUpdateResult != kUpdateNormalCompletion || Movie::instance()->IsRecording())
                {
                        canUpdate = false;
                }
	}

        // This and the following voodoo comes, effectively, from Bungie's code.
        if(theUpdateResult == kUpdateChangeLevel)
        {
                theElapsedTime = 0;
        }

	/* Game is over. */
	if(theUpdateResult == kUpdateGameOver) 
	{
		game_timed_out();
		theElapsedTime = 0;
	} 
	else if (theElapsedTime)
	{
		update_interface(theElapsedTime);
		update_fades();
	}

	check_recording_replaying();

	// ZZZ: Prediction!
	bool didPredict = false;
	
	if(theUpdateResult == kUpdateNormalCompletion && sPredictionWanted)
	{
		NetUpdateUnconfirmedActionFlags();

		// We use "2" to make sure there's always room for our one set of elements.
		// (thePredictiveQueues should always hold only 0 or 1 element for each player.)
		ActionQueues	thePredictiveQueues(dynamic_world->player_count, 2, true);

		// Observe, since we don't use a speed-limiter in predictive mode, that there cannot be flags
		// stranded in the GameQueue.  Unfortunately this approach will mispredict if a script is
		// controlling the local player.  We could be smarter about it if that eventually becomes an issue.
		for ( ; sPredictedTicks < NetGetUnconfirmedActionFlagsCount(); sPredictedTicks++)
		{
			// Real -> predictive transition, if necessary
			enter_predictive_mode();

			// Enqueue stuff into thePredictiveQueues
			for(short thePlayerIndex = 0; thePlayerIndex < dynamic_world->player_count; thePlayerIndex++)
			{
				uint32 theFlags = (thePlayerIndex == local_player_index) ? NetGetUnconfirmedActionFlag(sPredictedTicks) : sMostRecentFlagsForPlayer[thePlayerIndex];
				thePredictiveQueues.enqueueActionFlags(thePlayerIndex, &theFlags, 1);
			}
			
			// update_players() will dequeue the elements we just put in there
			update_players(&thePredictiveQueues, true);

			didPredict = true;
			
		} // loop while local player has flags we haven't used for prediction

	} // if we should predict

	// we return separately 1. "whether to redraw" and 2. "how many game-ticks elapsed"
        return std::pair<bool, int16>(didPredict || theElapsedTime != 0, theElapsedTime);
}
 int32 availableCapacity() const { return GetRealActionQueues()->availableCapacity(mPlayerIndex); }
 void reset(int32 inTick) { mWriteTick = inTick; GetRealActionQueues()->resetQueue(mPlayerIndex); }