Пример #1
0
void FCEUSS_Save(char *fname)
{
  FILE *st=NULL;
  char *fn;

  if(geniestage==1)
  {
   FCEU_DispMessage("Cannot save FCS in GG screen.");
   return;
  }

  if(fname)
   st=FCEUD_UTF8fopen(fname, "wb");
  else
  {
   st=FCEUD_UTF8fopen(fn=FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0),"wb");
   free(fn);
  }

  if(st == NULL)
  {
   FCEU_DispMessage("State %d save error.",CurrentState);
   return;
  }

  FCEUSS_SaveFP(st);

  SaveStateStatus[CurrentState]=1;
  fclose(st);
  FCEU_DispMessage("State %d saved.",CurrentState);
}
Пример #2
0
void FCEUI_LoadState(char *fname) {
	StateShow = 0;

	FCEUMOV_Stop();

	/* For network play, be load the state locally, and then save the state to a temporary file,
		   and send that.  This insures that if an older state is loaded that is missing some
		   information expected in newer save states, desynchronization won't occur(at least not
		   from this ;)).
	*/
	if (FCEUSS_Load(fname))
		if (FCEUnetplay) {
			char *fn = FCEU_MakeFName(FCEUMKF_NPTEMP, 0, 0);
			MEM_TYPE *fp;

			if ((fp = fopen(fn, "wb"))) {
				if (FCEUSS_SaveFP(fp)) {
					fclose(fp);
					FCEUNET_SendFile(FCEUNPCMD_LOADSTATE, fn);
				} else fclose(fp);
				unlink(fn);
			}
			free(fn);
		}
}
Пример #3
0
void FCEUSS_Save(char *fname) {
	MEM_TYPE *st = NULL;
	char *fn;

	if (geniestage == 1) {
		FCEU_DispMessage("Cannot save FCS in GG screen.");
		return;
	}

#ifdef HAVE_MEMSTREAM
	st = memstream_open(1);
#else
	if (fname)
		st = FCEUD_UTF8fopen(fname, "wb");
	else {
		st = FCEUD_UTF8fopen(fn = FCEU_MakeFName(FCEUMKF_STATE, CurrentState, 0), "wb");
		free(fn);
	}

	if (st == NULL) {
		FCEU_DispMessage("State %d save error.", CurrentState);
		return;
	}
#endif

	FCEUSS_SaveFP(st);

	SaveStateStatus[CurrentState] = 1;
	fclose(st);
#ifndef HAVE_MEMSTREAM
	FCEU_DispMessage("State %d saved.", CurrentState);
#endif
}
Пример #4
0
void NetplayUpdate(uint8 *joyp)
{
 static uint8 buf[5];  /* 4 play states, + command/extra byte */
 static uint8 joypb[4];

 memcpy(joypb,joyp,4);

 /* This shouldn't happen, but just in case.  0xFF is used as a command escape elsewhere. */
 if(joypb[0] == 0xFF)
  joypb[0] = 0xF;
 #ifdef NETWORK
 if(!netdcount)
  if(!FCEUD_SendData(joypb,numlocal))
  {
   NetError();
   return;
  }

 if(!netdcount)
 do
 {
  if(!FCEUD_RecvData(buf,5))
  {
   NetError();
   return;
  }

  switch(buf[4])
  {
   default: FCEU_DoSimpleCommand(buf[4]);break;
   case FCEUNPCMD_TEXT:
           {
      uint8 *tbuf;
      uint32 len = FCEU_de32lsb(buf);

      if(len > 100000)  // Insanity check!
      {
       NetError();
       return;
      }
      tbuf = malloc(len + 1);
      tbuf[len] = 0;
      if(!FCEUD_RecvData(tbuf, len))
      {
       NetError();
       free(tbuf);
       return;
      }
      FCEUD_NetplayText(tbuf);
      free(tbuf);
           }
           break;
   case FCEUNPCMD_SAVESTATE:
          {
             char *fn;
        FILE *fp;

        /* Send the cheats first, then the save state, since
           there might be a frame or two in between the two sendfile
           commands on the server side.
        */
        fn = FCEU_MakeFName(FCEUMKF_CHEAT,0,0);
        //if(!
        FCEUNET_SendFile(FCEUNPCMD_LOADCHEATS,fn);

             // {
             //  free(fn);
             //  return;
             // }
        free(fn);
        if(!FCEUnetplay) return;

        fn = FCEU_MakeFName(FCEUMKF_NPTEMP,0,0);
        fp = fopen(fn, "wb");
        if(FCEUSS_SaveFP(fp))
        {
         fclose(fp);
         if(!FCEUNET_SendFile(FCEUNPCMD_LOADSTATE, fn))
         {
          unlink(fn);
          free(fn);
          return;
         }
         unlink(fn);
         free(fn);
        }
        else
        {
         fclose(fp);
         FCEUD_PrintError("File error.  (K)ill, (M)aim, (D)estroy?  Now!");
         unlink(fn);
         free(fn);
         return;
        }

          }
         break;
   case FCEUNPCMD_LOADCHEATS:
        {
         FILE *fp = FetchFile(FCEU_de32lsb(buf));
         if(!fp) return;
         FCEU_FlushGameCheats(0,1);
         FCEU_LoadGameCheats(fp);
        }
        break;
 case FCEUNPCMD_LOADSTATE:
        {
         FILE *fp = FetchFile(FCEU_de32lsb(buf));
         if(!fp) return;
         if(FCEUSS_LoadFP(fp))
         {
          fclose(fp);
          FCEU_DispMessage("Remote state loaded.");
         } else FCEUD_PrintError("File error.  (K)ill, (M)aim, (D)estroy?");
          }
          break;
  }
 } while(buf[4]);
 #endif

 netdcount=(netdcount+1)%netdivisor;

 memcpy(netjoy,buf,4);
 *(uint32 *)joyp=*(uint32 *)netjoy;
}
Пример #5
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);
}