Beispiel #1
0
bool savestate_save(EMUFILE* outstream)
{
#ifdef HAVE_JIT 
	arm_jit_sync();
#endif

	EMUFILE_MEMORY ms;
	EMUFILE* os = outstream;
   os->fseek(32,SEEK_SET); //skip the header
   writechunks(os);

	//save the length of the file
	u32 len = os->ftell();

	u32 comprlen = 0xFFFFFFFF;
	u8* cbuf;

	//dump the header
	outstream->fseek(0,SEEK_SET);
	outstream->fwrite(magic,16);
	write32le(SAVESTATE_VERSION,outstream);
	write32le(EMU_DESMUME_VERSION_NUMERIC(),outstream); //desmume version
	write32le(len,outstream); //uncompressed length
	write32le(comprlen,outstream); //compressed length (-1 if it is not compressed)

	return true;
}
Beispiel #2
0
void HISTORY::save(EMUFILE *os, bool really_save)
{
	if (really_save)
	{
		int real_pos, last_tick = 0;
		// write "HISTORY" string
		os->fwrite(historySaveID, HISTORY_ID_LEN);
		// write vars
		write32le(historyCursorPos, os);
		write32le(historyTotalItems, os);
		// write items starting from history_start_pos
		for (int i = 0; i < historyTotalItems; ++i)
		{
			real_pos = (historyStartPos + i) % historySize;
			snapshots[real_pos].save(os);
			bookmarkBackups[real_pos].save(os);
			os->fwrite(&currentBranchNumberBackups[real_pos], 1);
			if (i / SAVING_HISTORY_PROGRESSBAR_UPDATE_RATE > last_tick)
			{
				playback.setProgressbar(i, historyTotalItems);
				last_tick = i / PROGRESSBAR_UPDATE_RATE;
			}
		}
	} else
	{
		// write "HISTORX" string
		os->fwrite(historySkipSaveID, HISTORY_ID_LEN);
	}
}
Beispiel #3
0
static int savestate_WriteChunk(EMUFILE* os, int type, const SFORMAT *sf)
{
	write32le(type,os);
	if(!sf) return 4;
	int bsize = SubWrite((EMUFILE*)0,sf);
	write32le(bsize,os);

	if(!SubWrite(os,sf))
	{
		return 8;
	}
	return (bsize+8);
}
Beispiel #4
0
bool BackupDevice::save_state(EMUFILE* os)
{
	u32 savePos = fpMC->ftell();
	std::vector<u8> data(fsize);
	fpMC->fseek(0, SEEK_SET);
	fread((char*)&data[0], 1, fsize, fpMC->get_fp());

	u32 version = 5;
	//v0
	write32le(version,os);
	write32le(write_enable,os);
	write32le(com,os);
	write32le(addr_size,os);
	write32le(addr_counter,os);
	write32le((u32)state,os);
	writebuffer(data,os);
	writebuffer(data_autodetect,os);
	//v1
	write32le(addr,os);
	//v2
	write8le(motionInitState,os);
	write8le(motionFlag,os);
	//v3
	writebool(reset_command_state,os);
	//v4
	write8le(write_protect,os);
	//v5
	write32le(savePos,os);

	fpMC->fseek(savePos, SEEK_SET);

	data.clear();

	return true;
}
Beispiel #5
0
int writebuffer(std::vector<u8>& vec, EMUFILE* os)
{
	u32 size = vec.size();
	write32le(size,os);
	if(size>0) os->fwrite((char*)&vec[0],size);
	return 1;
}
Beispiel #6
0
 void writeTo(uint8_t *Buf) override {
   uint8_t *P = Buf + FileOff;
   for (Chunk *C : Chunks) {
     write32le(P, C->getRVA());
     P += 4;
   }
 }
Beispiel #7
0
void write32(bool be,void *p,uint32_t d)
{
  if (be)
    write32be(p,d);
  else
    write32le(p,d);
}
Beispiel #8
0
static void mmu_savestate(EMUFILE* os)
{
	u32 version = 8;
	write32le(version,os);
	
	//version 2:
	MMU_new.backupDevice.save_state(os);
	
	//version 3:
	MMU_new.gxstat.savestate(os);
	for(int i=0;i<2;i++)
		for(int j=0;j<4;j++)
			MMU_new.dma[i][j].savestate(os);

	MMU_timing.arm9codeFetch.savestate(os, version);
	MMU_timing.arm9dataFetch.savestate(os, version);
	MMU_timing.arm7codeFetch.savestate(os, version);
	MMU_timing.arm7dataFetch.savestate(os, version);
	MMU_timing.arm9codeCache.savestate(os, version);
	MMU_timing.arm9dataCache.savestate(os, version);

	//version 4:
	MMU_new.sqrt.savestate(os);
	MMU_new.div.savestate(os);

	//version 6:
	MMU_new.dsi_tsc.save_state(os);

	//version 8:
	os->write32le(MMU.fw.size);
	os->fwrite(MMU.fw.data,MMU.fw.size);
}
Beispiel #9
0
int FCEUSS_SaveFP(MEM_TYPE *st) {
	static uint32 totalsize;
	uint8 header[16] = { 0 };

	header[0] = 'F';
	header[1] = 'C';
	header[2] = 'S';
	header[3] = 0xFF;

	header[3] = 0xFF;
	FCEU_en32lsb(header + 8, FCEU_VERSION_NUMERIC);
	fwrite(header, 1, 16, st);
	FCEUPPU_SaveState();
	FCEUSND_SaveState();
	totalsize = WriteStateChunk(st, 1, SFCPU);
	totalsize += WriteStateChunk(st, 2, SFCPUC);
	totalsize += WriteStateChunk(st, 3, FCEUPPU_STATEINFO);
	totalsize += WriteStateChunk(st, 4, FCEUCTRL_STATEINFO);
	totalsize += WriteStateChunk(st, 5, FCEUSND_STATEINFO);
	if (SPreSave) SPreSave();
	totalsize += WriteStateChunk(st, 0x10, SFMDATA);
	if (SPreSave) SPostSave();

	fseek(st, 4, SEEK_SET);
	write32le(totalsize, st);
	return(1);
}
Beispiel #10
0
 void writeTo(uint8_t *Buf) override {
   // An import-by-ordinal slot has MSB 1 to indicate that
   // this is import-by-ordinal (and not import-by-name).
   if (Config->is64()) {
     write64le(Buf + FileOff, (1ULL << 63) | Ordinal);
   } else {
     write32le(Buf + FileOff, (1ULL << 31) | Ordinal);
   }
 }
Beispiel #11
0
static void cp15_savestate(EMUFILE* os)
{
	//version
	write32le(1,os);

	cp15.saveone(os);
	//ARM7 not have coprocessor
	//cp15_saveone((armcp15_t *)NDS_ARM7.coproc[15],os);
}
Beispiel #12
0
void EMUFILE::writeMemoryStream(EMUFILE_MEMORY* ms)
{
	s32 size = (s32)ms->size();
	write32le(size);
	if(size>0)
	{
		std::vector<u8>* vec = ms->get_vec();
		fwrite(&vec->at(0),size);
	}
}
Beispiel #13
0
static int WriteStateChunk(MEM_TYPE *st, int type, SFORMAT *sf) {
	int bsize;

	fputc(type, st);

	bsize = SubWrite(0, sf);
	write32le(bsize, st);

	if (!SubWrite(st, sf)) return(0);
	return(bsize + 5);
}
Beispiel #14
0
static void savestate_WriteChunk(EMUFILE* os, int type, void (*saveproc)(EMUFILE* os))
{
	u32 pos1 = os->ftell();

	//write the type, size(placeholder), and data
	write32le(type,os);
	os->fseek(4, SEEK_CUR); // skip the size, we write that later
	saveproc(os);

	//get the size
	u32 pos2 = os->ftell();
	assert(pos2 != (u32)-1); // if this assert fails, saveproc did something bad
	u32 size = (pos2 - pos1) - (2 * sizeof(u32));

	//fill in the actual size
	os->fseek(pos1 + sizeof(u32),SEEK_SET);
	write32le(size,os);
	os->fseek(pos2,SEEK_SET);

/*
// old version of this function,
// for reference in case the new one above starts misbehaving somehow:

	// - this is retarded. why not write placeholders for size and then write directly to the stream
	//and then go back and fill them in

	//get the size
	memorystream mstemp;
	saveproc(&mstemp);
	mstemp.flush();
	u32 size = mstemp.size();

	//write the type, size, and data
	write32le(type,os);
	write32le(size,os);
	os->write(mstemp.buf(),size);
*/
}
Beispiel #15
0
bool BackupDevice::save_state(std::ostream* os)
{
	int version = 1;
	write32le(version,os);
	write32le(write_enable,os);
	write32le(com,os);
	write32le(addr_size,os);
	write32le(addr_counter,os);
	write32le((u32)state,os);
	writebuffer(data,os);
	writebuffer(data_autodetect,os);
	write32le(addr,os);
	return true;
}
Beispiel #16
0
bool BackupDevice::save_state(EMUFILE* os)
{
	size_t elements_read;
	u32 version = 5;
	u32 savePos = fpMC->ftell();
	std::vector<u8> data(fsize);

	fpMC->fseek(0, SEEK_SET);
	if (data.size() != 0)
		elements_read = fread(&data[0], 1, fsize, fpMC->get_fp());
	if (elements_read != fsize)
		printf(
			"Expected %u bytes from saved state but read %lu.\n",
			fsize,
			elements_read
		);

	//v0
	write32le(version,os);
	write32le(write_enable,os);
	write32le(com,os);
	write32le(addr_size,os);
	write32le(addr_counter,os);
	write32le((u32)state,os);
	writebuffer(data,os);
	writebuffer(data_autodetect,os);
	//v1
	write32le(addr,os);
	//v2
	write8le(motionInitState,os);
	write8le(motionFlag,os);
	//v3
	writebool(reset_command_state,os);
	//v4
	write8le(write_protect,os);
	//v5
	write32le(savePos,os);

	fpMC->fseek(savePos, SEEK_SET);

	data.clear();

	return true;
}
Beispiel #17
0
static int SubWrite(FILE *st, SFORMAT *sf)
{
 uint32 acc=0;

 while(sf->v)
 {
  if(sf->s==~0)    /* Link to another struct.  */
  {
   uint32 tmp;

   if(!(tmp=SubWrite(st,(SFORMAT *)sf->v)))
    return(0);
   acc+=tmp;
   sf++;
   continue;
  }

  acc+=8;      /* Description + size */
  acc+=sf->s&(~RLSB);

  if(st)      /* Are we writing or calculating the size of this block? */
  {
   fwrite(sf->desc,1,4,st);
   write32le(sf->s&(~RLSB),st);

   #ifndef LSB_FIRST
   if(sf->s&RLSB)
    FlipByteOrder(sf->v,sf->s&(~RLSB));
   #endif

   fwrite((uint8 *)sf->v,1,sf->s&(~RLSB),st);
   /* Now restore the original byte order. */
   #ifndef LSB_FIRST
   if(sf->s&RLSB)
    FlipByteOrder(sf->v,sf->s&(~RLSB));
   #endif
  }
  sf++;
 }

 return(acc);
}
Beispiel #18
0
bool BackupDevice::save_state(EMUFILE* os)
{
	u32 version = 2;
	//v0
	write32le(version,os);
	write32le(write_enable,os);
	write32le(com,os);
	write32le(addr_size,os);
	write32le(addr_counter,os);
	write32le((u32)state,os);
	writebuffer(data,os);
	writebuffer(data_autodetect,os);
	//v1
	write32le(addr,os);
	//v2
	write8le(motionInitState,os);
	write8le(motionFlag,os);
	return true;
}
Beispiel #19
0
int FCEUSS_SaveFP(FILE *st)
{
  static uint32 totalsize;
  static uint8 header[16]="FCS";

  memset(header+4,0,13);
  header[3]=0xFF;
  FCEU_en32lsb(header + 8, FCEU_VERSION_NUMERIC);
  fwrite(header,1,16,st);
  FCEUPPU_SaveState();
  FCEUSND_SaveState();
  totalsize=WriteStateChunk(st,1,SFCPU);
  totalsize+=WriteStateChunk(st,2,SFCPUC);
  totalsize+=WriteStateChunk(st,3,FCEUPPU_STATEINFO);
  totalsize+=WriteStateChunk(st,4,FCEUCTRL_STATEINFO);
  totalsize+=WriteStateChunk(st,5,FCEUSND_STATEINFO);
  if(SPreSave) SPreSave();
  totalsize+=WriteStateChunk(st,0x10,SFMDATA);
  if(SPreSave) SPostSave();

  fseek(st,4,SEEK_SET);
  write32le(totalsize,st);
  return(1);
}
Beispiel #20
0
void BackupDevice::flush()
{
	//never use save files if we are in movie mode
	if(isMovieMode) return;

	if (filename.length() == 0) return;

	EMUFILE* outf = new EMUFILE_FILE(filename.c_str(),"wb");
	if(!outf->fail())
	{
		if(data.size()>0)
			outf->fwrite(&data[0],data.size());
		
		//write the footer. we use a footer so that we can maximize the chance of the
		//save file being recognized as a raw save file by other emulators etc.
		
		//first, pad up to the next largest known save size.
		u32 size = data.size();
		u32 padSize = pad_up_size(size);

		for(u32 i=size;i<padSize;i++)
			outf->fputc(kUninitializedSaveDataValue);

		//this is just for humans to read
		outf->fprintf("|<--Snip above here to create a raw sav by excluding this DeSmuME savedata footer:");

		//and now the actual footer
		write32le(size,outf); //the size of data that has actually been written
		write32le(padSize,outf); //the size we padded it to
		write32le(info.type,outf); //save memory type
		write32le(addr_size,outf);
		write32le(info.size,outf); //save memory size
		write32le(0,outf); //version number
		outf->fprintf("%s", kDesmumeSaveCookie); //this is what we'll use to recognize the desmume format save

		delete outf;
	}
	else
	{
		delete outf;
		printf("Unable to open savefile %s\n", filename.c_str());
	}
}
Beispiel #21
0
void SNAPSHOT::save(EMUFILE *os)
{
	// write vars
	write32le(keyFrame, os);
	write32le(startFrame, os);
	write32le(endFrame, os);
	write32le(consecutivenessTag, os);
	write32le(recordedJoypadDifferenceBits, os);
	write32le(modificationType, os);
	// write description
	int len = strlen(description);
	write8le(len, os);
	os->fwrite(&description[0], len);
	// save InputLog data
	inputlog.save(os);
	// save LagLog data
	laglog.save(os);
	// save Markers data
	markers.save(os);
}
Beispiel #22
0
void GREENZONE::save(EMUFILE *os, int save_type)
{
	if (save_type != GREENZONE_SAVING_MODE_NO)
	{
		collectCurrentState();		// in case the project is being saved before the greenzone.update() was called within current frame
		runGreenzoneCleaning();
		if (greenzoneSize > (int)savestates.size())
			greenzoneSize = savestates.size();
		// write "GREENZONE" string
		os->fwrite(greenzone_save_id, GREENZONE_ID_LEN);
		// write LagLog
		lagLog.save(os);
		// write size
		write32le(greenzoneSize, os);
		// write Playback cursor position
		write32le(currFrameCounter, os);
	}
	int frame, size;
	int last_tick = 0;

	switch (save_type)
	{
		case GREENZONE_SAVING_MODE_ALL:
		{
			// write savestates
			for (frame = 0; frame < greenzoneSize; ++frame)
			{
				// update TASEditor progressbar from time to time
				if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
				{
					playback.setProgressbar(frame, greenzoneSize);
					last_tick = frame / PROGRESSBAR_UPDATE_RATE;
				}
				if (!savestates[frame].size()) continue;
				write32le(frame, os);
				// write savestate
				size = savestates[frame].size();
				write32le(size, os);
				os->fwrite(&savestates[frame][0], size);
			}
			// write -1 as eof for greenzone
			write32le(-1, os);
			break;
		}
		case GREENZONE_SAVING_MODE_16TH:
		{
			// write savestates
			for (frame = 0; frame < greenzoneSize; ++frame)
			{
				if (!(frame & 0xF) || frame == currFrameCounter)
				{
					// update TASEditor progressbar from time to time
					if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
					{
						playback.setProgressbar(frame, greenzoneSize);
						last_tick = frame / PROGRESSBAR_UPDATE_RATE;
					}
					if (!savestates[frame].size()) continue;
					write32le(frame, os);
					// write savestate
					size = savestates[frame].size();
					write32le(size, os);
					os->fwrite(&savestates[frame][0], size);
				}
			}
			// write -1 as eof for greenzone
			write32le(-1, os);
			break;
		}
		case GREENZONE_SAVING_MODE_MARKED:
		{
			// write savestates
			for (frame = 0; frame < greenzoneSize; ++frame)
			{
				if (markersManager.getMarkerAtFrame(frame) || frame == currFrameCounter)
				{
					// update TASEditor progressbar from time to time
					if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
					{
						playback.setProgressbar(frame, greenzoneSize);
						last_tick = frame / PROGRESSBAR_UPDATE_RATE;
					}
					if (!savestates[frame].size()) continue;
					write32le(frame, os);
					// write savestate
					size = savestates[frame].size();
					write32le(size, os);
					os->fwrite(&savestates[frame][0], size);
				}
			}
			// write -1 as eof for greenzone
			write32le(-1, os);
			break;
		}
		case GREENZONE_SAVING_MODE_NO:
		{
			// write "GREENZONX" string
			os->fwrite(greenzone_skipsave_id, GREENZONE_ID_LEN);
			// write LagLog
			lagLog.save(os);
			// write Playback cursor position
			write32le(currFrameCounter, os);
			if (currFrameCounter > 0)
			{
				// write ONE savestate for currFrameCounter
				collectCurrentState();
				int size = savestates[currFrameCounter].size();
				write32le(size, os);
				os->fwrite(&savestates[currFrameCounter][0], size);
			}
			break;
		}
	}
}
Beispiel #23
0
static void FlushHeader(void)
{
    if(current <= 0)
        return;// only write header data if recording

    FILE* fp = slots[current - 1];
    if(fp == 0)
        return;

    unsigned long loc = ftell(fp);
    fseek(fp, 4, SEEK_SET);
    write32le(MOVIE_VERSION, fp);
    fseek(fp, 12, SEEK_SET);
    write32le(framecount, fp);
    write32le(rerecord_count, fp);
    write32le(frameptr, fp);
    fseek(fp, 32, SEEK_SET);
    fwrite(FCEUGameInfo->MD5, 1, 16, fp);	// write ROM checksum
    write32le(FCEU_VERSION_NUMERIC, fp);	// write emu version used

    // write ROM name used
    fseek(fp, 52, SEEK_SET);
    char str[512];
    fgets(str,512,fp);
    str[511]='\0';
    int strdiff=strlen(FileBase)-strlen(str);
    if(strdiff)
    {
        // resize the whole damn movie because the ROM name in the header is of variable length
        int off=52;
        fseek(fp, 52, SEEK_SET);
        do {
            off++;
        } while(fgetc(fp) && !feof(fp) && !ferror(fp));

        if(feof(fp) || ferror(fp))
        {
            fseek(fp, loc, SEEK_SET);
            return;
        }

        fseek(fp, 0, SEEK_END);
        uint32 fsize=ftell(fp)-off;
        char* ctemp=(char*)FCEU_malloc(fsize*sizeof(char)+4);
        if(!ctemp)
        {
            fseek(fp, loc, SEEK_SET);
            return;
        }
        fseek(fp, off, SEEK_SET);
        fread(ctemp, 1,fsize, fp);
        fseek(fp, 52+strlen(FileBase)+1, SEEK_SET);
        int wrote = fwrite(ctemp, fsize,1, fp);
        FCEU_free(ctemp);
        if(!wrote)
        {
            fseek(fp, loc, SEEK_SET);
            return;
        }

        if(loc >= firstframeoffset)
            loc += strdiff;
        savestate_offset += strdiff;
        firstframeoffset += strdiff;
        fseek(fp, 24, SEEK_SET);
        write32le(savestate_offset, fp);
        write32le(firstframeoffset, fp);
    }
    fseek(fp, 52, SEEK_SET);
    fputs(FileBase, fp);
    fputc('\0', fp);

    fseek(fp, loc, SEEK_SET);
}
Beispiel #24
0
static int SubWrite(EMUFILE* os, const SFORMAT *sf)
{
	uint32 acc=0;

#ifdef DEBUG
	std::set<std::string> keyset;
#endif

	const SFORMAT* temp = sf;
	while(temp->v) {
		const SFORMAT* seek = sf;
		while(seek->v && seek != temp) {
			if(!strcmp(seek->desc,temp->desc)) {
				printf("ERROR! duplicated chunk name: %s\n", temp->desc);
			}
			seek++;
		}
		temp++;
	}

	while(sf->v)
	{
		//not supported right now
		//if(sf->size==~0)		//Link to another struct
		//{
		//	uint32 tmp;

		//	if(!(tmp=SubWrite(os,(SFORMAT *)sf->v)))
		//		return(0);
		//	acc+=tmp;
		//	sf++;
		//	continue;
		//}

		int count = sf->count;
		int size = sf->size;

        //add size of current node to the accumulator
		acc += 4 + sizeof(sf->size) + sizeof(sf->count);
		acc += count * size;

		if(os)			//Are we writing or calculating the size of this block?
		{
			os->fwrite(sf->desc,4);
			write32le(sf->size,os);
			write32le(sf->count,os);

			#ifdef DEBUG
			//make sure we dont dup any keys
			if(keyset.find(sf->desc) != keyset.end())
			{
				printf("duplicate save key!\n");
				assert(false);
			}
			keyset.insert(sf->desc);
			#endif


#ifdef MSB_FIRST
         if(size == 1) {
            //special case: write a huge byte array
            os->fwrite((char *)sf->v,count);
         } else {
            for(int i=0;i<count;i++) {
               FlipByteOrder((u8*)sf->v + i*size, size);
               os->fwrite((char*)sf->v + i*size,size);
               //Now restore the original byte order.
               FlipByteOrder((u8*)sf->v + i*size, size);
            }
         }
#else
         // no need to ever loop one at a time if not flipping byte order
         os->fwrite((char *)sf->v,size*count);
#endif
		}
		sf++;
	}

	return(acc);
}
Beispiel #25
0
void EMUFILE::write32le(u32* val)
{
	write32le(*val);
}
Beispiel #26
0
// Save state
void armcp15_t::saveone(EMUFILE* os)
{
	write32le(IDCode,os);
	write32le(cacheType,os);
    write32le(TCMSize,os);
    write32le(ctrl,os);
    write32le(DCConfig,os);
    write32le(ICConfig,os);
    write32le(writeBuffCtrl,os);
    write32le(und,os);
    write32le(DaccessPerm,os);
    write32le(IaccessPerm,os);
	for(int i=0;i<8;i++) write32le(protectBaseSize[i],os);
    write32le(cacheOp,os);
    write32le(DcacheLock,os);
    write32le(IcacheLock,os);
    write32le(ITCMRegion,os);
    write32le(DTCMRegion,os);
    write32le(processID,os);
    write32le(RAM_TAG,os);
    write32le(testState,os);
    write32le(cacheDbg,os);
    for(int i=0;i<8;i++) write32le(regionWriteMask_USR[i],os);
    for(int i=0;i<8;i++) write32le(regionWriteMask_SYS[i],os);
    for(int i=0;i<8;i++) write32le(regionReadMask_USR[i],os);
    for(int i=0;i<8;i++) write32le(regionReadMask_SYS[i],os);
    for(int i=0;i<8;i++) write32le(regionExecuteMask_USR[i],os);
    for(int i=0;i<8;i++) write32le(regionExecuteMask_SYS[i],os);
    for(int i=0;i<8;i++) write32le(regionWriteSet_USR[i],os);
    for(int i=0;i<8;i++) write32le(regionWriteSet_SYS[i],os);
    for(int i=0;i<8;i++) write32le(regionReadSet_USR[i],os);
    for(int i=0;i<8;i++) write32le(regionReadSet_SYS[i],os);
    for(int i=0;i<8;i++) write32le(regionExecuteSet_USR[i],os);
    for(int i=0;i<8;i++) write32le(regionExecuteSet_SYS[i],os);
}
Beispiel #27
0
void FCEUI_SaveMovie(char *fname, uint8 flags, const char* metadata)
{
    FILE *fp;
    char *fn;
    int poweron=0;
    uint8 padding[4] = {0,0,0,0};
    int n_padding;

    FCEUI_StopMovie();

    char origname[512];
    if(fname)
    {
        fp = FCEUD_UTF8fopen(fname, "wb");
        strcpy(origname,fname);
    }
    else
    {
        fp=FCEUD_UTF8fopen(fn=FCEU_MakeFName(FCEUMKF_MOVIE,CurrentMovie,0),"wb");
        strcpy(origname,fn);
        free(fn);
    }

    if(!fp) return;

// don't need the movieSyncHackOn sync hack for newly recorded movies
    flags |= MOVIE_FLAG_NOSYNCHACK;
    resetDMCacc=movieSyncHackOn=0;

// add PAL flag
    if(FCEUI_GetCurrentVidSystem(0,0))
        flags |= MOVIE_FLAG_PAL;

    if(flags & MOVIE_FLAG_FROM_POWERON)
    {
        poweron=1;
        flags &= ~MOVIE_FLAG_FROM_POWERON;
        flags |= MOVIE_FLAG_FROM_RESET;
    }

// write header
    write32le(MOVIE_MAGIC, fp);
    write32le(MOVIE_VERSION, fp);
    fputc(flags, fp);
    fputc(0, fp);                      // reserved
    fputc(0, fp);                      // reserved
    fputc(0, fp);                      // reserved
    write32le(0, fp);                  // leave room for length frames
    write32le(0, fp);                  // leave room for rerecord count
    write32le(0, fp);                  // leave room for movie data size
    write32le(0, fp);                  // leave room for savestate_offset
    write32le(0, fp);                  // leave room for offset_to_controller_data
    fwrite(FCEUGameInfo->MD5, 1, 16, fp);	// write ROM checksum
    write32le(FCEU_VERSION_NUMERIC, fp);	// write emu version used
    fputs(FileBase, fp);					// write ROM name used
    fputc(0, fp);
    if(metadata)
    {
        if(strlen(metadata) < MOVIE_MAX_METADATA)
            fputs(metadata, fp);
        else
            fwrite(metadata, 1, MOVIE_MAX_METADATA-1, fp);
    }
    fputc(0, fp);

// add padding
    n_padding = (4 - (ftell(fp) & 0x3)) & 0x3;
    fwrite(padding, 1, n_padding, fp);

    if(flags & MOVIE_FLAG_FROM_RESET)
    {
        if(poweron)
        {
            // make a for-movie-recording power-on clear the game's save data, too
            // (note: FCEU makes a save state immediately after this and that loads that on movie playback)
            extern char lastLoadedGameName [2048];
            extern int disableBatteryLoading, suppressAddPowerCommand;
            suppressAddPowerCommand=1;
            disableBatteryLoading=1;
            suppressMovieStop=1;
            {
                // NOTE:  this will NOT write an FCEUNPCMD_POWER into the movie file
                FCEUGI * gi = FCEUI_LoadGame(lastLoadedGameName);
                if(!gi)
                    PowerNES(); // and neither will this, if it can even happen
            }
            suppressMovieStop=0;
            disableBatteryLoading=0;
            suppressAddPowerCommand=0;
        }
    }

    savestate_offset = ftell(fp);
    FCEUSS_SaveFP(fp);
    fseek(fp, 0, SEEK_END);

    ResetInputTypes();

// add padding
    n_padding = (4 - (ftell(fp) & 0x3)) & 0x3;
    fwrite(padding, 1, n_padding, fp);

    firstframeoffset = ftell(fp);

// finish header
    fseek(fp, 24, SEEK_SET);			// offset_to_savestate offset
    write32le(savestate_offset, fp);
    write32le(firstframeoffset, fp);

    fseek(fp, firstframeoffset, SEEK_SET);

// set recording flag
    current=CurrentMovie;

    movie_readonly = 0;
    frameptr = 0;
    framecount = 0;
    rerecord_count = 0;
    slots[current] = fp;
    memset(joop,0,sizeof(joop));
    current++;
    framets=0;
    nextd = -1;

// trigger a reset
    if(flags & MOVIE_FLAG_FROM_RESET)
    {
        if(poweron)
        {
            PowerNES();							// NOTE:  this will write an FCEUNPCMD_POWER into the movie file
        }
        else
            ResetNES();							// NOTE:  this will write an FCEUNPCMD_RESET into the movie file
    }
    if(!fname)
        FCEUI_SelectMovie(CurrentMovie,1);       /* Quick hack to display status. */
    else
        FCEU_DispMessage("Movie recording started.");

    strcpy(curMovieFilename, origname);
}
Beispiel #28
0
 void writeTo(uint8_t *Buf) override {
   write32le(Buf + FileOff, HintName->getRVA());
 }
Beispiel #29
0
void mic_savestate(EMUFILE* os)
{
	write32le(-1,os);
}
Beispiel #30
0
void writebool(bool b, EMUFILE* os) { write32le(b?1:0,os); }