⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 movie.cpp

📁 SFC游戏模拟器 snes9x 1.43 的原代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{		S9xReset();		// save only SRAM for a from-reset snapshot		result=(READ_STREAM(SRAM, 0x20000, stream) == 0x20000) ? SUCCESS : WRONG_FORMAT;	}	else	{		result=S9xUnfreezeFromStream(stream);	}	CLOSE_STREAM(stream);	if(result!=SUCCESS)	{		return result;	}	if(!(fd=fopen(filename, read_only ? "rb" : "rb+")))		return FILE_NOT_FOUND;	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	read_frame_controller_data();	strncpy(Movie.Filename, filename, _MAX_PATH);	Movie.Filename[_MAX_PATH-1]='\0';	Movie.CurrentFrame=0;	Movie.ReadOnly=read_only;	change_state(MOVIE_STATE_PLAY);	S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REPLAY);	return SUCCESS;}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;	if(!(fd=fopen(filename, "wb")))		return FILE_NOT_FOUND;	// 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.SaveStateOffset=SMV_HEADER_SIZE+(sizeof(uint16)*metadata_length);	Movie.ControllerDataOffset=0;	Movie.ControllersMask=controllers_mask;	Movie.Opts=opts;	if(Settings.PAL)	{		Movie.Opts |= MOVIE_OPT_PAL;	}	else	{		Movie.Opts &= ~MOVIE_OPT_PAL;	}	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)];		int i;		for(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);	}	// write snapshot	fn=dup(fileno(fd));	fclose(fd);	// lseek(fn, Movie.SaveStateOffset, SEEK_SET);	if(!(stream=REOPEN_STREAM(fn, "ab")))		return FILE_NOT_FOUND;	if(opts & MOVIE_OPT_FROM_RESET)	{		S9xReset();		// save only SRAM for a from-reset snapshot		WRITE_STREAM(SRAM, 0x20000, stream);	}	else	{		S9xFreezeToStream(stream);	}	CLOSE_STREAM(stream);	if(!(fd=fopen(filename, "rb+")))		return FILE_NOT_FOUND;	fseek(fd, 0, SEEK_END);	Movie.ControllerDataOffset=(uint32)ftell(fd);	// write "baseline" controller data	Movie.File=fd;	Movie.BytesPerFrame=bytes_per_frame();	Movie.InputBufferPtr=Movie.InputBuffer;	write_frame_controller_data();	strncpy(Movie.Filename, filename, _MAX_PATH);	Movie.Filename[_MAX_PATH-1]='\0';	Movie.CurrentFrame=0;	Movie.ReadOnly=false;	change_state(MOVIE_STATE_RECORD);	S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_RECORD);	return SUCCESS;}void S9xMovieUpdate (){	switch(Movie.State)	{	case MOVIE_STATE_PLAY:		if(Movie.CurrentFrame>=Movie.MaxFrame)		{			change_state(MOVIE_STATE_NONE);			S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_END);			return;		}		else		{			if(Movie.FrameDisplay)			{				sprintf(Movie.FrameDisplayString, "Playing frame: %d", Movie.CurrentFrame);				S9xMessage (S9X_INFO, S9X_MOVIE_INFO, Movie.FrameDisplayString);			}			read_frame_controller_data();			++Movie.CurrentFrame;		}		break;	case MOVIE_STATE_RECORD:		{			if(Movie.FrameDisplay)			{				sprintf(Movie.FrameDisplayString, "Recording frame: %d", Movie.CurrentFrame);				S9xMessage (S9X_INFO, S9X_MOVIE_INFO, Movie.FrameDisplayString);			}			write_frame_controller_data();			++Movie.CurrentFrame;			Movie.MaxFrame=Movie.CurrentFrame;			fwrite((Movie.InputBufferPtr - Movie.BytesPerFrame), 1, Movie.BytesPerFrame, Movie.File);		}		break;	default:		break;	}}void S9xMovieStop (bool8 suppress_message){	if(Movie.State!=MOVIE_STATE_NONE)	{		change_state(MOVIE_STATE_NONE);		if(!suppress_message)			S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_STOP);	}}int S9xMovieGetInfo (const char* filename, struct MovieInfo* info){	FILE* fd;	int result;	SMovie local_movie;	int metadata_length;	memset(info, 0, sizeof(*info));	if(!(fd=fopen(filename, "rb")))		return FILE_NOT_FOUND;	if((result=(read_movie_header(fd, &local_movie)))!=SUCCESS)		return result;	info->TimeCreated=(time_t)local_movie.MovieId;	info->LengthFrames=local_movie.MaxFrame;	info->RerecordCount=local_movie.RerecordCount;	info->Opts=local_movie.Opts;	info->ControllersMask=local_movie.ControllersMask;	if(local_movie.SaveStateOffset > SMV_HEADER_SIZE)	{		uint8 meta_buf[MOVIE_MAX_METADATA * sizeof(uint16)];		int i;		metadata_length=((int)local_movie.SaveStateOffset-SMV_HEADER_SIZE)/sizeof(uint16);		metadata_length=(metadata_length>=MOVIE_MAX_METADATA) ? MOVIE_MAX_METADATA-1 : metadata_length;		metadata_length=(int)fread(meta_buf, sizeof(uint16), metadata_length, fd);		for(i=0; i<metadata_length; ++i)		{			uint16 c=meta_buf[i+i] | (meta_buf[i+i+1] << 8);			info->Metadata[i]=(wchar_t)c;		}		info->Metadata[i]='\0';	}	else	{		info->Metadata[0]='\0';	}	fclose(fd);	if(access(filename, W_OK))		info->ReadOnly=true;	return SUCCESS;}bool8 S9xMovieActive (){	return (Movie.State!=MOVIE_STATE_NONE);}bool8 S9xMovieReadOnly (){	if(!S9xMovieActive())		return false;	return Movie.ReadOnly;}uint32 S9xMovieGetId (){	if(!S9xMovieActive())		return 0;	return Movie.MovieId;}uint32 S9xMovieGetLength (){	if(!S9xMovieActive())		return 0;	return Movie.MaxFrame;}uint32 S9xMovieGetFrameCounter (){	if(!S9xMovieActive())		return 0;	return Movie.CurrentFrame;}void S9xMovieToggleFrameDisplay (){	Movie.FrameDisplay = !Movie.FrameDisplay;	if(!Movie.FrameDisplay)	{		GFX.InfoStringTimeout = 1;	}}void S9xMovieFreeze (uint8** buf, uint32* size){	// sanity check	if(!S9xMovieActive())	{		return;	}	*buf = NULL;	*size = 0;	// compute size needed for the buffer	uint32 size_needed = 4*3;			// room for MovieId, CurrentFrame, and MaxFrame	size_needed += (uint32)(Movie.BytesPerFrame * (Movie.MaxFrame+1));	*buf=new uint8[size_needed];	*size=size_needed;	uint8* ptr = *buf;	if(!ptr)	{		return;	}	Write32(Movie.MovieId, ptr);	Write32(Movie.CurrentFrame, ptr);	Write32(Movie.MaxFrame, ptr);	memcpy(ptr, Movie.InputBuffer, Movie.BytesPerFrame * (Movie.MaxFrame+1));}bool8 S9xMovieUnfreeze (const uint8* buf, uint32 size){	// sanity check	if(!S9xMovieActive())	{		return false;	}	const uint8* ptr = buf;	if(size < 4*3)	{		return false;	}	uint32 movie_id = Read32(ptr);	uint32 current_frame = Read32(ptr);	uint32 max_frame = Read32(ptr);	uint32 space_needed = (Movie.BytesPerFrame * (max_frame+1));	if(movie_id != Movie.MovieId ||		current_frame > max_frame ||		space_needed > size)	{		return false;	}	if(!Movie.ReadOnly)	{		// here, we are going to take the input data from the savestate		// and make it the input data for the current movie, then continue		// writing new input data at the currentframe pointer		change_state(MOVIE_STATE_RECORD);		S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_RERECORD);		Movie.CurrentFrame = current_frame;		Movie.MaxFrame = max_frame;		++Movie.RerecordCount;		reserve_buffer_space(space_needed);		memcpy(Movie.InputBuffer, ptr, space_needed);		flush_movie();		fseek(Movie.File, Movie.ControllerDataOffset+(Movie.BytesPerFrame * (Movie.CurrentFrame+1)), SEEK_SET);	}	else	{		// here, we are going to keep the input data from the movie file		// and simply rewind to the currentframe pointer		// this will cause a desync if the savestate is not in sync		// with the on-disk recording data, but it's easily solved		// by loading another savestate or playing the movie from the beginning		// and older savestate might have a currentframe pointer past		// the end of the input data, so check for that here		if(current_frame > Movie.MaxFrame)		{			return false;		}		change_state(MOVIE_STATE_PLAY);		S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REWIND);		Movie.CurrentFrame = current_frame;	}	Movie.InputBufferPtr = Movie.InputBuffer + (Movie.BytesPerFrame * Movie.CurrentFrame);	read_frame_controller_data();	return true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -