Exemplo n.º 1
0
int S9xMovieOpen (const char* filename, bool8 read_only)
{
	FILE* fd;
	STREAM stream;
	int result;
	int fn;

	char movie_filename [_MAX_PATH];
#ifdef __WIN32__
	_fullpath(movie_filename, filename, _MAX_PATH);
#else
	strcpy(movie_filename, filename);
#endif

	if(!(fd=fopen(movie_filename, "rb+")))
		if(!(fd=fopen(movie_filename, "rb")))
			return FILE_NOT_FOUND;
		else
			read_only = TRUE;

	const bool8 wasPaused = Settings.Paused;

	// stop current movie before opening
	change_state(MOVIE_STATE_NONE);

	// read header
	if((result=read_movie_header(fd, &Movie))!=SUCCESS)
	{
		fclose(fd);
		return result;
	}

	read_movie_extrarominfo(fd, &Movie);

	fn=dup(fileno(fd));
	fclose(fd);

	// apparently this lseek is necessary
	lseek(fn, Movie.SaveStateOffset, SEEK_SET);
	if(!(stream=REOPEN_STREAM(fn, "rb")))
		return FILE_NOT_FOUND;

	// store previous, before changing to the movie's settings
	store_previous_settings();

	// set from movie
	restore_movie_settings();

	if(Movie.Opts & MOVIE_OPT_FROM_RESET)
	{
		Movie.State = MOVIE_STATE_PLAY; // prevent NSRT controller switching (in S9xPostRomInit)
		if(!Memory.LoadLastROM())
			S9xReset();
		Memory.ClearSRAM(false); // in case the SRAM read fails
		Movie.State = MOVIE_STATE_NONE;
		S9xMovieResetControls();
		// save only SRAM for a from-reset snapshot
		result=(READ_STREAM(Memory.SRAM, 0x20000, stream) == 0x20000) ? SUCCESS : WRONG_FORMAT;
	}
	else
	{
		result=S9xUnfreezeFromStream(stream);
	}
	CLOSE_STREAM(stream);

	if(result!=SUCCESS)
	{
		return result;
	}

	if(!(fd=fopen(movie_filename, "rb+")))
		if(!(fd=fopen(movie_filename, "rb")))
			return FILE_NOT_FOUND;
		else
			read_only = TRUE;

	if(fseek(fd, Movie.ControllerDataOffset, SEEK_SET))
		return WRONG_FORMAT;

	// read controller data
	Movie.File=fd;
	Movie.BytesPerSample=bytes_per_sample();
	Movie.InputBufferPtr=Movie.InputBuffer;
	uint32 to_read=Movie.BytesPerSample * (Movie.MaxSample+1);
	reserve_buffer_space(to_read);
	fread(Movie.InputBufferPtr, 1, to_read, fd);

	// read "baseline" controller data
	if(Movie.MaxSample && Movie.MaxFrame)
		read_frame_controller_data(true);

	strncpy(Movie.Filename, movie_filename, _MAX_PATH);
	Movie.Filename[_MAX_PATH-1]='\0';
	Movie.CurrentFrame=0;
	Movie.CurrentSample=0;
	Movie.ReadOnly=read_only;
	change_state(MOVIE_STATE_PLAY);

	Settings.Paused = wasPaused;

	Movie.RecordedThisSession = false;
	S9xUpdateFrameCounter(-1);

	S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REPLAY);
	return SUCCESS;
}
Exemplo n.º 2
0
int S9xMovieCreate (const char* filename, uint8 controllers_mask, uint8 opts, const wchar_t* metadata, int metadata_length)
{
	FILE* fd;
	STREAM stream;
	int fn;

	if(controllers_mask==0)
		return WRONG_FORMAT;

	char movie_filename [_MAX_PATH];
#ifdef __WIN32__
	_fullpath(movie_filename, filename, _MAX_PATH);
#else
	strcpy(movie_filename, filename);
#endif

	if(!(fd=fopen(movie_filename, "wb")))
		return FILE_NOT_FOUND;

	const bool8 wasPaused = Settings.Paused;

	// stop current movie before opening
	change_state(MOVIE_STATE_NONE);

	if(metadata_length>MOVIE_MAX_METADATA)
	{
		metadata_length=MOVIE_MAX_METADATA;
	}

	Movie.MovieId=(uint32)time(NULL);
	Movie.RerecordCount=0;
	Movie.MaxFrame=0;
	Movie.MaxSample=0;
	Movie.SaveStateOffset=SMV_HEADER_SIZE+(sizeof(uint16)*metadata_length) + SMV_EXTRAROMINFO_SIZE;
	Movie.ControllerDataOffset=0;
	Movie.ControllersMask=controllers_mask;
	Movie.Opts=opts;
	Movie.SyncFlags=MOVIE_SYNC_DATA_EXISTS|MOVIE_SYNC_HASROMINFO;

	// store previous, in case we switch to playback later
	store_previous_settings();

	// store settings in movie
	store_movie_settings();

	// extra rom info
	Movie.ROMCRC32 = Memory.ROMCRC32;
	strncpy(Movie.ROMName, Memory.ROMName, 23);


	write_movie_header(fd, &Movie);


	// convert wchar_t metadata string/array to a uint16 array
	if(metadata_length>0)
	{
		uint8 meta_buf[MOVIE_MAX_METADATA * sizeof(uint16)];
		for(int i=0; i<metadata_length; ++i)
		{
			uint16 c=(uint16)metadata[i];
			meta_buf[i+i]  =(uint8)(c&0xff);
			meta_buf[i+i+1]=(uint8)((c>>8)&0xff);
		}

		fwrite(meta_buf, sizeof(uint16), metadata_length, fd);
		assert(!ferror(fd));
	}
Exemplo n.º 3
0
int S9xMovieOpen (const char* filename, bool8 read_only, uint8 sync_flags, uint8 sync_flags2)
{
	FILE* fd;
	STREAM stream;
	int result;
	int fn;

	char movie_filename [_MAX_PATH];
#ifdef WIN32
	_fullpath(movie_filename, filename, _MAX_PATH);
#else
	strcpy(movie_filename, filename);
#endif

	if(!(fd=fopen(movie_filename, "rb+")))
		if(!(fd=fopen(movie_filename, "rb")))
			return FILE_NOT_FOUND;
		else
			read_only = TRUE;

	const bool8 wasPaused = Settings.Paused;
	const uint32 prevFrameTime = Settings.FrameTime;

	// stop current movie before opening
	change_state(MOVIE_STATE_NONE);

	// read header
	if((result=read_movie_header(fd, &Movie))!=SUCCESS)
	{
		fclose(fd);
		return result;
	}

	read_movie_extrarominfo(fd, &Movie);

	fn=dup(fileno(fd));
	fclose(fd);

	// apparently this lseek is necessary
	lseek(fn, Movie.SaveStateOffset, SEEK_SET);
	if(!(stream=REOPEN_STREAM(fn, "rb")))
		return FILE_NOT_FOUND;

	// store previous, before changing to the movie's settings
	store_previous_settings();

	// store default
	if (sync_flags & MOVIE_SYNC_DATA_EXISTS)
	{
		Settings.UseWIPAPUTiming = (sync_flags & MOVIE_SYNC_WIP1TIMING) ? TRUE : FALSE;
		Settings.SoundEnvelopeHeightReading = (sync_flags & MOVIE_SYNC_VOLUMEENVX) ? TRUE : FALSE;
		Settings.FakeMuteFix = (sync_flags & MOVIE_SYNC_FAKEMUTE) ? TRUE : FALSE;
		Settings.UpAndDown = (sync_flags & MOVIE_SYNC_LEFTRIGHT) ? TRUE : FALSE; // doesn't actually affect synchronization
		Settings.SoundSync = (sync_flags & MOVIE_SYNC_SYNCSOUND) ? TRUE : FALSE; // doesn't seem to affect synchronization
		Settings.InitFastROMSetting = (sync_flags2 & MOVIE_SYNC2_INIT_FASTROM) ? TRUE : FALSE;
		//Settings.ShutdownMaster = (sync_flags & MOVIE_SYNC_NOCPUSHUTDOWN) ? FALSE : TRUE;
	}

	// set from movie
	restore_movie_settings();

	if(Movie.Opts & MOVIE_OPT_FROM_RESET)
	{
		Movie.State = MOVIE_STATE_PLAY; // prevent NSRT controller switching (in S9xPostRomInit)
		if(!Memory.LoadLastROM())
			S9xReset();
		Memory.ClearSRAM(false); // in case the SRAM read fails
		Movie.State = MOVIE_STATE_NONE;

		// save only SRAM for a from-reset snapshot
		result=(READ_STREAM(Memory.SRAM, 0x20000, stream) == 0x20000) ? SUCCESS : WRONG_FORMAT;
	}
	else
	{
		result=S9xUnfreezeFromStream(stream);
	}
	CLOSE_STREAM(stream);

	if(result!=SUCCESS)
	{
		return result;
	}

	if(!(fd=fopen(movie_filename, "rb+")))
		if(!(fd=fopen(movie_filename, "rb")))
			return FILE_NOT_FOUND;
		else
			read_only = TRUE;

	if(fseek(fd, Movie.ControllerDataOffset, SEEK_SET))
		return WRONG_FORMAT;

	// read controller data
	Movie.File=fd;
	Movie.BytesPerFrame=bytes_per_frame();
	Movie.InputBufferPtr=Movie.InputBuffer;
	uint32 to_read=Movie.BytesPerFrame * (Movie.MaxFrame+1);
	reserve_buffer_space(to_read);
	fread(Movie.InputBufferPtr, 1, to_read, fd);

	// read "baseline" controller data
	if(Movie.MaxFrame)
		read_frame_controller_data();

	strncpy(Movie.Filename, movie_filename, _MAX_PATH);
	Movie.Filename[_MAX_PATH-1]='\0';
	Movie.CurrentFrame=0;
	Movie.ReadOnly=read_only;
	change_state(MOVIE_STATE_PLAY);

	Settings.Paused = wasPaused;
	Settings.FrameTime = prevFrameTime; // restore emulation speed

	Movie.RecordedThisSession = false;
	S9xUpdateFrameCounter(-1);

	Movie.RequiresReset = false;

	S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REPLAY);
	return SUCCESS;
}