Beispiel #1
0
void rewind_recording(
	void)
{
	if(replay.game_is_being_recorded)
	{
		/* This is unnecessary, because it is called from reset_player_queues, */
		/* which is always called from revert_game */
		/*
		FilmFile.SetLength(sizeof(recording_header));
		FilmFile.SetPosition(sizeof(recording_header));
		*/
		// Alternative that does not use "SetLength", but instead creates and re-creates the file.
		FilmFile.SetPosition(0);
		byte Header[SIZEOF_recording_header];
		FilmFile.Read(SIZEOF_recording_header,Header);
		FilmFile.Close();
		FilmFileSpec.Delete();
		FilmFileSpec.Create(_typecode_film);
		FilmFileSpec.Open(FilmFile,true);
		FilmFile.Write(SIZEOF_recording_header,Header);
		
		// Use the packed length here!!!
		replay.header.length= SIZEOF_recording_header;
	}
}
Beispiel #2
0
void stop_recording(
	void)
{
	if (replay.game_is_being_recorded)
	{
		replay.game_is_being_recorded = false;
		
		short player_index;
		int32 total_length;

		assert(replay.valid);
		for (player_index= 0; player_index<dynamic_world->player_count; player_index++)
		{
			save_recording_queue_chunk(player_index);
		}

		/* Rewrite the header, since it has the new length */
		FilmFile.SetPosition(0);
		byte Header[SIZEOF_recording_header];
		pack_recording_header(Header,&replay.header,1);

		// ZZZ: removing code that does stuff from assert() argument.  BUT...
		// should we really be asserting on this anyway?  I mean, the write could fail
		// in 'normal operation' too, not just when we screwed something up in writing the program?
		bool successfulWrite = FilmFile.Write(SIZEOF_recording_header,Header);
		assert(successfulWrite);
		
		FilmFile.GetLength(total_length);
		assert(total_length==replay.header.length);
		
		FilmFile.Close();
	}

	replay.valid= false;
}
Beispiel #3
0
/* Note that we _must_ set the header information before we start recording!! */
void start_recording(
	void)
{
	assert(!replay.valid);
	replay.valid= true;
	
	if(get_recording_filedesc(FilmFileSpec))
		FilmFileSpec.Delete();

	if (FilmFileSpec.Create(_typecode_film))
	{
		/* I debate the validity of fsCurPerm here, but Alain had it, and it has been working */
		if (FilmFileSpec.Open(FilmFile,true))
		{
			replay.game_is_being_recorded= true;
	
			// save a header containing information about the game.
			byte Header[SIZEOF_recording_header];
			pack_recording_header(Header,&replay.header,1);
			FilmFile.Write(SIZEOF_recording_header,Header);
		}
	}
}
Beispiel #4
0
/*********************************************************************************************
 *
 * Function: save_recording_queue_chunk
 * Purpose:  saves one chunk of the queue to the recording file, using run-length encoding.
 *
 *********************************************************************************************/
void save_recording_queue_chunk(
	short player_index)
{
	uint8 *location;
	uint32 last_flag, count, flag = 0;
	int16 i, run_count, num_flags_saved, max_flags;
	static uint8 *buffer= NULL;
	ActionQueue *queue;
	
	// The data format is (run length (int16)) + (action flag (uint32))
	int DataSize = sizeof(int16) + sizeof(uint32);
	
	if (buffer == NULL)
		buffer = new byte[RECORD_CHUNK_SIZE * DataSize];
	
	location= buffer;
	count= 0; // keeps track of how many bytes we'll save.
	last_flag= (uint32)NONE;

	queue= get_player_recording_queue(player_index);
	
	// don't want to save too much stuff
	max_flags= MIN(RECORD_CHUNK_SIZE, get_recording_queue_size(player_index)); 

	// save what's in the queue
	run_count= num_flags_saved= 0;
	for (i = 0; i<max_flags; i++)
	{
		flag = queue->buffer[queue->read_index];
		INCREMENT_QUEUE_COUNTER(queue->read_index);
		
		if (i && flag != last_flag)
		{
			ValueToStream(location,run_count);
			ValueToStream(location,last_flag);
			count += DataSize;
			num_flags_saved += run_count;
			run_count = 1;
		}
		else
		{
			run_count++;
		}
		last_flag = flag;
	}
	
	// now save the final run
	ValueToStream(location,run_count);
	ValueToStream(location,last_flag);
	count += DataSize;
	num_flags_saved += run_count;
	
	if (max_flags<RECORD_CHUNK_SIZE)
	{
		short end_indicator = END_OF_RECORDING_INDICATOR;
		ValueToStream(location,end_indicator);
		int32 end_flag = 0;
		ValueToStream(location,end_flag);
		count += DataSize;
		num_flags_saved += RECORD_CHUNK_SIZE-max_flags;
	}
	
	FilmFile.Write(count,buffer);
	replay.header.length+= count;
		
	vwarn(num_flags_saved == RECORD_CHUNK_SIZE,
		csprintf(temporary, "bad recording: %d flags, max=%d, count = %u;dm #%p #%u", num_flags_saved, max_flags,
			count, buffer, count));
}