int
vsnprintf(char* inBuffer, size_t inBufferSize, const char* inFormat, va_list inArgs) {
    int theResult = vsprintf(inBuffer, inFormat, inArgs);

    // In case logging vsnprintf's a long string, don't warn while warning.
    static bool issuingWarning = false;

    if(theResult + 1 > inBufferSize && !issuingWarning) {
        issuingWarning = true;
        logWarning2("vsnprintf emulation wrote too many bytes (%d/%d)", theResult + 1, inBufferSize);
        issuingWarning = false;
    }

    return theResult;
}
Exemplo n.º 2
0
// ZZZ: if in predictive mode, restore the saved partial game-state (it'd better take us back
// to _exactly_ the same full game-state we saved earlier, else problems.)
static void
exit_predictive_mode()
{
	if(sPredictedTicks > 0)
	{
		for(short i = 0; i < dynamic_world->player_count; i++)
		{
			player_data* player = get_player_data(i);
			
			assert(player->monster_index == sSavedPlayerData[i].monster_index);

			{
				// We *don't* restore this tiny part of the game-state back because
				// otherwise the player can't use [] to scroll the inventory panel.
				// [] scrolling happens outside the normal input/update system, so that's
				// enough to persuade me that not restoring this won't OOS any more often
				// than []-scrolling did before prediction.  :)
				int16 saved_interface_flags = player->interface_flags;
				int16 saved_interface_decay = player->interface_decay;
				
				*player = sSavedPlayerData[i];

				player->interface_flags = saved_interface_flags;
				player->interface_decay = saved_interface_decay;
			}

			if(sSavedPlayerData[i].monster_index != NONE)
			{
				assert(get_monster_data(sSavedPlayerData[i].monster_index)->object_index == sSavedPlayerMonsterData[i].object_index);

				*get_monster_data(sSavedPlayerData[i].monster_index) = sSavedPlayerMonsterData[i];
				
				if(sSavedPlayerMonsterData[i].object_index != NONE)
				{
					assert(get_object_data(sSavedPlayerMonsterData[i].object_index)->parasitic_object == sSavedPlayerObjectData[i].parasitic_object);

					remove_object_from_polygon_object_list(sSavedPlayerMonsterData[i].object_index);
					
					*get_object_data(sSavedPlayerMonsterData[i].object_index) = sSavedPlayerObjectData[i];

					// We have to defer this insertion since the object lists could still have other players
					// in their predictive locations etc. - we need to reconstruct everything exactly as it
					// was when we entered predictive mode.
					deferred_add_object_to_polygon_object_list(sSavedPlayerMonsterData[i].object_index, sSavedPlayerObjectNextObject[i]);
					
					if(sSavedPlayerObjectData[i].parasitic_object != NONE)
						*get_object_data(sSavedPlayerObjectData[i].parasitic_object) = sSavedPlayerParasiticObjectData[i];
				}
			}
		}

		perform_deferred_polygon_object_list_manipulations();
		
		sPredictedTicks = 0;

		// Sanity checking
		if(sSavedTickCount != dynamic_world->tick_count)
			logWarning2("saved tick count %d != dynamic_world->tick_count %d", sSavedTickCount, dynamic_world->tick_count);

		if(sSavedRandomSeed != get_random_seed())
			logWarning2("saved random seed %d != get_random_seed() %d", sSavedRandomSeed, get_random_seed());
	}
}