예제 #1
0
bool MDFNI_SaveState(const char *fname, const char *suffix, const MDFN_Surface *surface, const MDFN_Rect *DisplayRect, const int32 *LineWidths) noexcept
{
 bool ret = true;

 try
 {
  if(!MDFNGameInfo->StateAction)
  {
   throw MDFN_Error(0, _("Module \"%s\" doesn't support save states."), MDFNGameInfo->shortname);
  }

  if(MDFNnetplay && (MDFNGameInfo->SaveStateAltersState == true))
  {
   throw MDFN_Error(0, _("Module %s is not compatible with manual state saving during netplay."), MDFNGameInfo->shortname);
  }

  //
  //
  {
   MemoryStream st(65536);

   MDFNSS_SaveSM(&st, false, surface, DisplayRect, LineWidths);

   //
   //
   //
   GZFileStream gp(fname ? std::string(fname) : MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix),
			GZFileStream::MODE::WRITE, MDFN_GetSettingI("filesys.state_comp_level"));

   gp.write(st.map(), st.size());
   gp.close();
  }

  MDFND_SetStateStatus(NULL);

  if(!fname && !suffix)
  {
   SaveStateStatus[CurrentState] = true;
   RecentlySavedState = CurrentState;
   MDFN_DispMessage(_("State %d saved."), CurrentState);
  }
 }
 catch(std::exception &e)
 {
  if(!fname && !suffix)
   MDFN_DispMessage(_("State %d save error: %s"), CurrentState, e.what());
  else
   MDFN_PrintError("%s", e.what());

  if(MDFNnetplay)
   MDFND_NetplayText(e.what(), false);

  ret = false;
 }

 return(ret);
}
예제 #2
0
void MDFNI_SaveSnapshot(const MDFN_Surface *src, const MDFN_Rect *rect, const MDFN_Rect *LineWidths)
{
#ifndef WII
  FileWrapper *pp = NULL;

  try
  {
    std::string fn;
    int u = 0;

    try
    {
      pp = new FileWrapper(MDFN_MakeFName(MDFNMKF_SNAP_DAT, 0, NULL).c_str(), FileWrapper::MODE_READ);
    }
    catch(std::exception &e)
    {

    }

    if(pp)
    {
      if(pp->scanf("%d", &u) != 1)
        u = 0;

      delete pp;
      pp = NULL;
    }

    pp = new FileWrapper(MDFN_MakeFName(MDFNMKF_SNAP_DAT, 0, NULL).c_str(), FileWrapper::MODE_WRITE);

    pp->seek(0, SEEK_SET);
    pp->printf("%d\n", u + 1);

    delete pp;
    pp = NULL;

    fn = MDFN_MakeFName(MDFNMKF_SNAP, u, "png");

    PNGWrite(fn.c_str(), src, *rect, LineWidths);

    MDFN_DispMessage(_("Screen snapshot %d saved."), u);
  }
  catch(std::exception &e)
  {
    if(pp)
    {
      delete pp;
      pp = NULL;
    }

    MDFN_PrintError(_("Error saving screen snapshot: %s"), e.what());
    MDFN_DispMessage(_("Error saving screen snapshot: %s"), e.what());
  }
#endif
}
예제 #3
0
int MDFNSS_Load(const char *fname, const char *suffix)
{
	gzFile st;

	if(!MDFNGameInfo->StateAction)
	{
		MDFN_DispMessage("Module \"%s\" doesn't support save states.", MDFNGameInfo->shortname);
		return(0);
	}

	if(fname)
		st=gzopen(fname, "rb");
	else
	{
		st=gzopen(MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix).c_str(),"rb");
	}

	if(st == NULL)
	{
		if(!fname && !suffix)
		{
			MDFN_DispMessage("State %d load error.",CurrentState);
			SaveStateStatus[CurrentState]=0;
		}
		return(0);
	}

	if(MDFNSS_LoadFP(st))
	{
		MDFNI_DisplayState();

		if(!fname && !suffix)
		{
			LoadStateMovie((char*)MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix).c_str());
			SaveStateStatus[CurrentState]=1;
			MDFN_DispMessage("State %d loaded.",CurrentState);
			SaveStateStatus[CurrentState]=1;
		}
		gzclose(st);
		return(1);
	}
	else
	{
		SaveStateStatus[CurrentState]=1;
		MDFN_DispMessage("State %d read error!",CurrentState);
		gzclose(st);
		return(0);
	}
}
예제 #4
0
static int StateAction(StateMem *sm, int load, int data_only)
{
 if(Genie_BIOSInstalled())
 {
  if(!data_only)
   MDFN_DispMessage(_("Cannot use states in GG Screen."));
  return(0);
 }

 if(!X6502_StateAction(sm, load, data_only))
  return(0);

 if(!MDFNPPU_StateAction(sm, load, data_only))
  return(0);

 if(!MDFNSND_StateAction(sm, load, data_only))
  return(0);

 if(!load || load >= 0x0500)
 {
  if(!NESINPUT_StateAction(sm, load, data_only))
   return(0);
 }

 if(GameInterface->StateAction)
 {
  if(!GameInterface->StateAction(sm, load, data_only))
   return(0);
 }

 return(1);
}
예제 #5
0
 virtual void Frame(const void *data)
 {
  uint16 new_buttons = MDFN_de16lsb((uint8 *)data);
  bool mode_changed = false;

  if((old_raw_buttons ^ new_buttons) & (1 << 12) & new_buttons)
  {
   mode1 = !mode1;
   mode_changed = true;
  }

  if((old_raw_buttons ^ new_buttons) & (1 << 14) & new_buttons)
  {
   mode2 = !mode2;
   mode_changed = true;
  }

  if(mode_changed)
   MDFN_DispMessage(_("Pad %d - MODE 1: %s, MODE 2: %s"), which + 1, (mode1 ? "B" : "A"), (mode2 ? "B" : "A"));

  buttons = new_buttons & ~( (1 << 12) | (1 << 14));
  buttons |= mode1 << 12;
  buttons |= mode2 << 14;

  old_raw_buttons = new_buttons;
  //printf("%d %08x\n", which, buttons);
 }
예제 #6
0
void MDFNI_SaveMovie(char *fname, uint32 *fb, MDFN_Rect *LineWidths)
{
    gzFile fp;

    if(current < 0)	/* Can't interrupt playback.*/
        return;

    if(current > 0)	/* Stop saving. */
    {
        StopRecording();
        return;
    }

    memset(&RewindBuffer, 0, sizeof(StateMem));
    RewindBuffer.initial_malloc = 16;

    current=CurrentMovie;

    if(fname)
        fp = gzopen(fname, "wb3");
    else
    {
        fp=gzopen(MDFN_MakeFName(MDFNMKF_MOVIE,CurrentMovie,0).c_str(),"wb3");
    }

    if(!fp) return;

    MDFNSS_SaveFP(fp, fb, LineWidths);
    gzseek(fp, 0, SEEK_END);
    gzflush(fp, Z_SYNC_FLUSH); // Flush output so that previews will still work right while
    // the movie is being recorded.  Purely cosmetic. :)
    slots[current] = fp;
    current++;
    MDFN_DispMessage(_("Movie recording started."));
}
예제 #7
0
int MDFNSS_Save(const char *fname, const char *suffix, const MDFN_Surface *surface, const MDFN_Rect *DisplayRect, const MDFN_Rect *LineWidths)
{
	StateMem st;

	memset(&st, 0, sizeof(StateMem));


	if(!MDFNGameInfo->StateAction)
	{
		MDFN_DispMessage("Module \"%s\" doesn't support save states.", MDFNGameInfo->shortname);
		return(0);
	}

	if(!MDFNSS_SaveSM(&st, 1, 0, surface, DisplayRect, LineWidths))
	{
		if(st.data)
			free(st.data);
		if(!fname && !suffix)
			MDFN_DispMessage("State %d save error.", CurrentState);
		return(0);
	}

	if(!MDFN_DumpToFile(fname ? fname : MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix).c_str(), 6, st.data, st.len))
	{
		SaveStateStatus[CurrentState] = 0;
		free(st.data);

		if(!fname && !suffix)
			MDFN_DispMessage("State %d save error.",CurrentState);

		return(0);
	}

	std::string bleh = MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix);
	SaveStateMovie(bleh);

	free(st.data);

	SaveStateStatus[CurrentState] = 1;
	RecentlySavedState = CurrentState;

	if(!fname && !suffix)
		MDFN_DispMessage("State %d saved.",CurrentState);

	return(1);
}
예제 #8
0
int MDFNSS_Load(const char *fname, const char *suffix)
{
	gzFile st;

	if(fname)
		st=gzopen(fname, "rb");
	else
	{
		st=gzopen(MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix).c_str(),"rb");
	}

	if(st == NULL)
	{
		if(!fname && !suffix)
		{
			MDFN_DispMessage(_("State %d load error."),CurrentState);
			SaveStateStatus[CurrentState]=0;
		}
		return(0);
	}

	

	if(MDFNSS_LoadFP(st))
	{
		MDFNI_DisplayState();
		LoadStateMovie((char*)MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix).c_str());
		
		if(!fname && !suffix)
		{
			SaveStateStatus[CurrentState]=1;
			MDFN_DispMessage(_("State %d loaded."),CurrentState);
			SaveStateStatus[CurrentState]=1;
		}
		gzclose(st);
		return(1);
	}
	else
	{
		SaveStateStatus[CurrentState]=1;
		MDFN_DispMessage(_("State %d read error!"),CurrentState);
		gzclose(st);
		return(0);
	}
}
예제 #9
0
void InputDevice_DualShock::SetAMCT(bool enabled)
{
 amct_enabled = enabled;
 if(amct_enabled)
     analog_mode = false;
 else
     analog_mode = true;

  MDFN_DispMessage(_("%s: Analog toggle is %s, sticks are %s"), gp_name.c_str(), amct_enabled ? _("ENABLED") : _("DISABLED"), analog_mode ? _("ON") : _("OFF"));  
}
예제 #10
0
void MDFNI_LoadMovie(char *fname)
{
    gzFile fp;
//puts("KAO");

    if(current > 0)        /* Can't interrupt recording.*/
        return;
#ifdef NETWORK
    if(MDFNnetplay)	/* Playback is UNPOSSIBLE during netplay. */
    {
        MDFN_DispMessage(_("Can't play movies during netplay."));
        return;
    }
#endif

    if(current < 0)        /* Stop playback. */
    {
        StopPlayback();
        return;
    }

    if(fname)
        fp = gzopen(fname, "rb");
    else
    {
        fp=gzopen(MDFN_MakeFName(MDFNMKF_MOVIE,CurrentMovie,0).c_str(),"rb");
    }

    if(!fp) return;

    if(!MDFNSS_LoadFP(fp))
    {
        MDFN_DispMessage(_("Error loading state portion of the movie."));
        return;
    }
    current = CurrentMovie;
    slots[current] = fp;

    current = -1 - current;
    MovieStatus[CurrentMovie] = 1;
    MDFN_DispMessage(_("Movie playback started."));
}
예제 #11
0
static void StopPlayback(void)
{
    if(RewindBuffer.data)
    {
        RewindBuffer.data = NULL;
    }

    gzclose(slots[-1 - current]);
    current=0;
    MDFN_DispMessage(_("Movie playback stopped."));
}
예제 #12
0
void InputDevice_DualShock::UpdateInput(const void *data)
{
    uint8 *d8 = (uint8 *)data;

    buttons[0] = d8[0];
    buttons[1] = d8[1];
    cur_ana_button_state = d8[2] & 0x01;

    for(int stick = 0; stick < 2; stick++)
    {
        for(int axis = 0; axis < 2; axis++)
        {
            int32 tmp;

            tmp = 32768 + MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 4) - ((int32)MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 8) * 32768 / 32767);
            tmp >>= 8;

            axes[stick][axis] = tmp;
        }
    }

    if(da_rumble_compat == false)
    {
        uint8 sneaky_weaky = 0;

        if(rumble_param[0] == 0x01)
            sneaky_weaky = 0xFF;

        MDFN_en32lsb(&d8[4 + 32 + 0], (sneaky_weaky << 0) | (rumble_param[1] << 8));
    }
    else
    {
        uint8 sneaky_weaky = 0;

        if(((rumble_param[0] & 0xC0) == 0x40) && ((rumble_param[1] & 0x01) == 0x01))
            sneaky_weaky = 0xFF;

        MDFN_en32lsb(&d8[4 + 32 + 0], sneaky_weaky << 0);
    }

//printf("%d %d %d %d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]);

//
//
//
    CheckManualAnaModeChange();

    if(am_prev_info != analog_mode || aml_prev_info != analog_mode_locked)
    {
        MDFN_DispMessage(_("%s: Analog mode is %s(%s)."), gp_name.c_str(), analog_mode ? _("on") : _("off"), analog_mode_locked ? _("locked") : _("unlocked"));
    }
    am_prev_info = analog_mode;
    aml_prev_info = analog_mode_locked;
}
예제 #13
0
int MDFNSS_Save(const char *fname, const char *suffix, uint32 *fb, MDFN_Rect *LineWidths)
{
	StateMem st;

	memset(&st, 0, sizeof(StateMem));

	if(!MDFNSS_SaveSM(&st, 1, 0, fb, LineWidths))
	{
		if(st.data)
			free(st.data);
		if(!fname && !suffix)
			MDFN_DispMessage(_("State %d save error."), CurrentState);
		return(0);
	}

	if(!MDFN_DumpToFile(fname ? fname : MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix).c_str(), 6, st.data, st.len))
	{
		SaveStateStatus[CurrentState] = 0;
		free(st.data);

		if(!fname && !suffix)
			MDFN_DispMessage(_("State %d save error."),CurrentState);

		return(0);
	}

	SaveStateMovie((const char*)MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix).c_str());

	free(st.data);

	SaveStateStatus[CurrentState] = 1;
	RecentlySavedState = CurrentState;

	if(!fname && !suffix)
		MDFN_DispMessage(_("State %d saved."),CurrentState);

	return(1);
}
예제 #14
0
파일: main.cpp 프로젝트: CaoCaoBeard/pcejin
void LoadGame(){

	char szChoice[MAX_PATH]={0};
	OPENFILENAME ofn;
	ZeroMemory(&ofn, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = g_hWnd;
	ofn.lpstrFilter = "PC Engine Files (*.pce, *.cue, *.toc, *.sgx *.zip)\0*.pce;*.cue;*.toc;*.sgx;*.zip\0All files(*.*)\0*.*\0\0";
	ofn.lpstrFile = (LPSTR)szChoice;
	ofn.lpstrTitle = "Select a file to open";
	ofn.lpstrDefExt = "pce";
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
	if(GetOpenFileName(&ofn)) {
		pcejin.romLoaded = true;
		pcejin.started = true;
		if(strlen(szChoice) > 4 && (!strcasecmp(szChoice + strlen(szChoice) - 4, ".cue") || !strcasecmp(szChoice + strlen(szChoice) - 4, ".toc"))) {
			char ret[MAX_PATH];
			GetPrivateProfileString("Main", "Bios", "pce.cdbios PATH NOT SET", ret, MAX_PATH, IniName);
			if(std::string(ret) == "pce.cdbios PATH NOT SET") {
				pcejin.started = false;
				pcejin.romLoaded = false;
				MDFN_DispMessage("specify your PCE CD bios");
				return;
			}
		}
		if(!MDFNI_LoadGame(szChoice)) {
			pcejin.started = false;
			pcejin.romLoaded = false;
			
		}
		if (AutoRWLoad)
		{
			//Open Ram Watch if its auto-load setting is checked
			OpenRWRecentFile(0);
			RamWatchHWnd = CreateDialog(winClass.hInstance, MAKEINTRESOURCE(IDD_RAMWATCH), g_hWnd, (DLGPROC) RamWatchProc);
		}
		StopMovie();
		ResetFrameCount();
		RecentROMs.UpdateRecentItems(szChoice);

		std::string romname = noExtension(RemovePath(szChoice));
		std::string temp = pcejin.versionName;
		GameName = romname;
		temp.append(" ");
		temp.append(romname);
		SetWindowText(g_hWnd, temp.c_str());
	}
}
예제 #15
0
static bool ValidateRawDataSector(uint8 *data, const uint32 lba)
{
 if(!edc_lec_check_and_correct(data, false))
 {
  MDFN_DispMessage(_("Uncorrectable data at sector %u"), lba);
  MDFN_PrintError(_("Uncorrectable data at sector %u"), lba);

  din.Flush();
  cd.data_transfer_done = false;

  CommandCCError(SENSEKEY_MEDIUM_ERROR, AP_LEC_UNCORRECTABLE_ERROR);
  return(false);
 }

 return(true);
}
예제 #16
0
void MDFNI_SaveMovie(char *fname, const MDFN_Surface *surface, const MDFN_Rect *DisplayRect, const int32 *LineWidths)
{
 gzFile fp;

 if(!MDFNGameInfo->StateAction)
  return;

 if(MDFNnetplay && (MDFNGameInfo->SaveStateAltersState == true))
 {
  char sb[256];
  trio_snprintf(sb, sizeof(sb), _("Module %s is not compatible with manual movie save starting/stopping during netplay."), MDFNGameInfo->shortname);
  MDFND_NetplayText((const uint8*)sb, false);
  return;
 }

 if(current < 0)	/* Can't interrupt playback.*/
  return;

 if(current > 0)	/* Stop saving. */
 {
  StopRecording();
  return;  
 }

 memset(&RewindBuffer, 0, sizeof(StateMem));
 RewindBuffer.initial_malloc = 16;

 current = CurrentMovie;

 if(fname)
  fp = gzopen(fname, "wb3");
 else
 {
  fp=gzopen(MDFN_MakeFName(MDFNMKF_MOVIE,CurrentMovie,0).c_str(),"wb3");
 }

 if(!fp) return;

 MDFNSS_SaveFP(fp, surface, DisplayRect, LineWidths);
 gzseek(fp, 0, SEEK_END);
 gzflush(fp, Z_SYNC_FLUSH); // Flush output so that previews will still work right while
			    // the movie is being recorded.  Purely cosmetic. :)
 slots[current] = fp;
 current++;
 MDFN_DispMessage(_("Movie recording started."));
}
예제 #17
0
int CDIF_ReadSector(uint8* pBuf, uint32 lba, uint32 nSectors)
{
 int ret = 0;

 while(nSectors--)
 {
  uint8 tmpbuf[2352 + 96];

  if(!CDIF_ReadRawSector(tmpbuf, lba))
  {
   puts("CDIF Raw Read error");
   return(FALSE);
  }

  if(!CDIF_ValidateRawSector(tmpbuf))
  {
   MDFN_DispMessage(_("Uncorrectable data at sector %d"), lba);
   MDFN_PrintError(_("Uncorrectable data at sector %d"), lba);
   return(false);
  }

  const int mode = tmpbuf[12 + 3];

  if(!ret)
   ret = mode;

  if(mode == 1)
  {
   memcpy(pBuf, &tmpbuf[12 + 4], 2048);
  }
  else if(mode == 2)
  {
   memcpy(pBuf, &tmpbuf[12 + 4 + 8], 2048);
  }
  else
  {
   printf("CDIF_ReadSector() invalid sector type at LBA=%u\n", (unsigned int)lba);
   return(false);
  }

  pBuf += 2048;
  lba++;
 }

 return(ret);
}
예제 #18
0
//
// This simulates the behavior of the actual DualShock(analog toggle button evaluation is suspended while DTR is active).
// Call in Update(), and whenever dtr goes inactive in the port access code.
void InputDevice_DualShock::CheckManualAnaModeChange(void)
{
 if(!dtr)
 {
  bool need_mode_toggle = false;

  if(amct_enabled)
  {
   if(buttons[0] == 0x09 && buttons[1] == 0x0f)
   {
    if(combo_anatoggle_counter == -1)
     combo_anatoggle_counter = 0;
    else if(combo_anatoggle_counter >= (44100 * 768))
    {
     need_mode_toggle = true;
     combo_anatoggle_counter = -2;
    }
   }
   else
    combo_anatoggle_counter = -1;
  }  
  else
  {
   combo_anatoggle_counter = -1;
   if(cur_ana_button_state && (cur_ana_button_state != prev_ana_button_state))
   {
    need_mode_toggle = true;
   }
  }

  if(need_mode_toggle)
  {
   if(analog_mode_locked)
   {
     //MDFN_DispMessage(_("%s: Analog mode is  %s."), gp_name.c_str(), analog_mode ? _("on") : _("off"));
     MDFN_DispMessage(_("%s: 2 Analog toggle is DISABLED, sticks are %s"), gp_name.c_str(), analog_mode ? _("ON") : _("OFF"));         
   }
   else
    analog_mode = !analog_mode;
  }

  prev_ana_button_state = cur_ana_button_state; 	// Don't move this outside of the if(!dtr) block!
 }
}
예제 #19
0
static void StopRecording(void)
{
    MDFNMOV_RecordState();
    if(MDFN_StateEvilIsRunning())
    {
        MDFN_StateEvilFlushMovieLove();
    }
    gzclose(slots[current-1]);
    MovieStatus[current - 1] = 1;
    RecentlySavedMovie = current - 1;
    current=0;
    MDFN_DispMessage(_("Movie recording stopped."));

    if(RewindBuffer.data)
    {
        //puts("Oops");
        free(RewindBuffer.data);
        RewindBuffer.data = NULL;
    }
}
예제 #20
0
void InputDevice_DualShock::UpdateInput(const void *data)
{
 uint8 *d8 = (uint8 *)data;
 uint8* const rumb_dp = &d8[3 + 16];

 buttons[0] = d8[0];
 buttons[1] = d8[1];
 cur_ana_button_state = d8[2] & 0x01;

 for(int stick = 0; stick < 2; stick++)
 {
  for(int axis = 0; axis < 2; axis++)
  {
     const uint8* aba = &d8[3] + stick * 8 + axis * 4;
   int32 tmp;

   //revert to 0.9.33, should be fixed on libretro side instead
   //tmp = 32767 + MDFN_de16lsb(&aba[0]) - MDFN_de16lsb(&aba[2]);
   //tmp = (tmp * 0x100) / 0xFFFF;
   
   tmp = 32768 + MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 4) - ((int32)MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 8) * 32768 / 32767);
   tmp >>= 8;
   axes[stick][axis] = tmp;
  }
 }

 //printf("%3d:%3d, %3d:%3d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]);

 //printf("RUMBLE: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", rumble_magic[0], rumble_magic[1], rumble_magic[2], rumble_magic[3], rumble_magic[4], rumble_magic[5]);
 //printf("%d, 0x%02x 0x%02x\n", da_rumble_compat, rumble_param[0], rumble_param[1]);
 if(da_rumble_compat == false)
 {
  uint8 sneaky_weaky = 0;

  if(rumble_param[0] == 0x01)
   sneaky_weaky = 0xFF;

   //revert to 0.9.33, should be fixed on libretro side instead
   //MDFN_en16lsb(rumb_dp, (sneaky_weaky << 0) | (rumble_param[1] << 8));
   
   MDFN_en32lsb(&d8[4 + 32 + 0], (sneaky_weaky << 0) | (rumble_param[1] << 8));
 }
 else
 {
  uint8 sneaky_weaky = 0;

  if(((rumble_param[0] & 0xC0) == 0x40) && ((rumble_param[1] & 0x01) == 0x01))
   sneaky_weaky = 0xFF;

   //revert to 0.9.33, should be fixed on libretro side instead
   //MDFN_en16lsb(rumb_dp, sneaky_weaky << 0);
   MDFN_en32lsb(&d8[4 + 32 + 0], sneaky_weaky << 0);
 }

 //printf("%d %d %d %d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]);

 //
 //
 //
 CheckManualAnaModeChange();

 if(am_prev_info != analog_mode || aml_prev_info != analog_mode_locked)
 {
	//MDFN_DispMessage(_("%s: Analog mode is %s(%s)."), gp_name.c_str(), analog_mode ? _("on") : _("off"), analog_mode_locked ? _("locked") : _("unlocked"));
    MDFN_DispMessage(_("%s: Analog toggle is %s, sticks are %s"), gp_name.c_str(), amct_enabled ? _("ENABLED") : _("DISABLED"), analog_mode ? _("ON") : _("OFF"));  
 }
 aml_prev_info = analog_mode_locked;
 am_prev_info = analog_mode;
}
예제 #21
0
/********************************************************
*							*
*	PC Engine CD Command 0xDE - Get Directory Info	*
*							*
********************************************************/
static void DoNEC_PCE_GETDIRINFO(const uint8 *cdb)
{
 // Problems:
 //	Returned data lengths on real PCE are not confirmed.
 //	Mode 0x03 behavior not tested on real PCE

 uint8 data_in[2048];
 uint32 data_in_size = 0;

 memset(data_in, 0, sizeof(data_in));

 switch(cdb[1])
 {
  default: MDFN_DispMessage("Unknown GETDIRINFO Mode: %02x", cdb[1]);
	   printf("Unknown GETDIRINFO Mode: %02x", cdb[1]);
  case 0x0:
   data_in[0] = U8_to_BCD(toc.first_track);
   data_in[1] = U8_to_BCD(toc.last_track);

   data_in_size = 2;
   break;

  case 0x1:
   {
    uint8 m, s, f;

    LBA_to_AMSF(toc.tracks[100].lba, &m, &s, &f);

    data_in[0] = U8_to_BCD(m);
    data_in[1] = U8_to_BCD(s);
    data_in[2] = U8_to_BCD(f);

    data_in_size = 3;
   }
   break;

  case 0x2:
   {
    uint8 m, s, f;
    int track = BCD_to_U8(cdb[2]);

    if(!track)
     track = 1;
    else if(cdb[2] == 0xAA)
    {
     track = 100;
    }
    else if(track > 99)
    {
     CommandCCError(SENSEKEY_ILLEGAL_REQUEST, NSE_INVALID_PARAMETER);
     return;
    }

    LBA_to_AMSF(toc.tracks[track].lba, &m, &s, &f);

    data_in[0] = U8_to_BCD(m);
    data_in[1] = U8_to_BCD(s);
    data_in[2] = U8_to_BCD(f);
    data_in[3] = toc.tracks[track].control;
    data_in_size = 4;
   }
   break;
 }

 DoSimpleDataIn(data_in, data_in_size);
}
예제 #22
0
static void ProcessCommand(const uint8 cmd, const uint32 raw_len, const char **PortDNames, void *PortData[], uint32 PortLen[], int NumPorts)
{
  switch(cmd)
  {
   case 0: break; // No command

   default: MDFN_DoSimpleCommand(cmd);
	    break;

   case MDFNNPCMD_INTEGRITY:
			SendIntegrity();
			break;

   case MDFNNPCMD_REQUEST_STATE:
			SendState();
	  	 	break;

   case MDFNNPCMD_LOADSTATE:
			RecvState(raw_len);
			MDFN_DispMessage(_("Remote state loaded."));
			break;

   case MDFNNPCMD_SERVERTEXT:
			{
			 static const uint32 MaxLength = 2000;
                         uint8 neobuf[MaxLength + 1];
                         char *textbuf = NULL;
                         const uint32 totallen = raw_len;

                         if(totallen > MaxLength) // Sanity check
                         {
                          throw MDFN_Error(0, _("Text length is too long: %u"), totallen);
                         }

                         MDFND_RecvData(neobuf, totallen);

			 neobuf[totallen] = 0;
			 trio_asprintf(&textbuf, "** %s", neobuf);
                         MDFND_NetplayText((UTF8*)textbuf, FALSE);
                         free(textbuf);
			}
			break;

   case MDFNNPCMD_ECHO:
			{
                         uint32 totallen = raw_len;
			 uint64 then_time;
			 uint64 now_time;

			 if(totallen != sizeof(then_time))
			 {
                          throw MDFN_Error(0, _("Echo response length is incorrect size: %u"), totallen);
			 }

                         MDFND_RecvData(&then_time, sizeof(then_time));

			 now_time = MDFND_GetTime();

                         char *textbuf = NULL;
			 trio_asprintf(&textbuf, _("*** Round-trip time: %llu ms"), (unsigned long long)(now_time - then_time));
                         MDFND_NetplayText((UTF8*)textbuf, FALSE);
                         free(textbuf);
			}
			break;

   case MDFNNPCMD_TEXT:
			{
			 static const uint32 MaxLength = 2000;
			 uint8 neobuf[MaxLength + 1];
			 const uint32 totallen = raw_len;
                         uint32 nicklen;
                         bool NetEcho = false;
                         char *textbuf = NULL;

			 if(totallen < 4)
			 {
			  throw MDFN_Error(0, _("Text command length is too short: %u"), totallen);
	  		 }

			 if(totallen > MaxLength) // Sanity check
			 {
                          throw MDFN_Error(0, _("Text command length is too long: %u"), totallen);
			 }

			 MDFND_RecvData(neobuf, totallen);

			 nicklen = MDFN_de32lsb(neobuf);
			 if(nicklen > (totallen - 4)) // Sanity check
			 {
			  throw MDFN_Error(0, _("Received nickname length is too long: %u"), nicklen);
			 }

                         neobuf[totallen] = 0;

			 if(nicklen)
			 {
			  uint8 nickbuf[nicklen + 1];
			  memcpy(nickbuf, neobuf + 4, nicklen);
			  nickbuf[nicklen] = 0;
			  if(OurNick && !strcasecmp(OurNick, (char *)nickbuf))
			  {
                           trio_asprintf(&textbuf, "> %s", &neobuf[4 + nicklen]);
			   NetEcho = true;
			  }
			  else
			   trio_asprintf(&textbuf, "<%s> %s", nickbuf, &neobuf[4 + nicklen]);
			 }
		         else
			 {
			  trio_asprintf(&textbuf, "* %s", &neobuf[4]);
			 }
                         MDFND_NetplayText((UTF8*)textbuf, NetEcho);
			 free(textbuf);
			}
			break;

   case MDFNNPCMD_NICKCHANGED:
			{
			 static const uint32 MaxLength = 2000;
                         uint8 neobuf[MaxLength + 1];
                         uint8 *newnick;
                         char *textbuf = NULL;
			 const uint32 len = raw_len;

                         if(len > MaxLength) // Sanity check
                         {
                          throw MDFN_Error(0, _("Nickname change length is too long: %u"), len);
                         }

                         MDFND_RecvData(neobuf, len);

			 neobuf[len] = 0;

			 newnick = (uint8*)strchr((char*)neobuf, '\n');

			 if(newnick)
			 {
			  bool IsMeow = FALSE;
			  *newnick = 0;
			  newnick++;
			  if(OurNick)
			  {
			   if(!strcasecmp((char*)neobuf, (char*)OurNick))
			   {
			    free(OurNick);
			    OurNick = strdup((char*)newnick);
			    textbuf = trio_aprintf(_("* You are now known as <%s>."), newnick);
			    IsMeow = TRUE;
			   }
			  }
			  if(!textbuf)
			   textbuf = trio_aprintf(_("* <%s> is now known as <%s>"), neobuf, newnick);
                          MDFND_NetplayText((UTF8*)textbuf, IsMeow);
			  free(textbuf);
			 }
			}
			break;

    case MDFNNPCMD_CTRL_CHANGE:
			{
			 const uint32 len = raw_len;

			 //
                         // Joined = true;
                         SendCommand(MDFNNPCMD_CTRL_CHANGE_ACK, len);
			 //
			 //
                         LocalInputStateSize = 0;
                         LocalPlayersMask = len;

                         for(int x = 0; x < MDFNGameInfo->InputInfo->InputPorts; x++)
                         {
                          if(LocalPlayersMask & (1 << x))
                           LocalInputStateSize += PortLen[x];
                         }
			}
			break;

   case MDFNNPCMD_CTRLR_SWAP_NOTIF:
			{
			 const uint32 cm = raw_len;
			 char textbuf[512];

			 trio_snprintf(textbuf, sizeof(textbuf), _("* All instances of controllers %u and %u have been swapped."), ((cm & 0xFF) + 1), ((cm >> 8) & 0xFF) + 1);
			 MDFND_NetplayText((UTF8*)textbuf, false);
			}
			break;

   case MDFNNPCMD_CTRLR_TAKE_NOTIF:
   case MDFNNPCMD_CTRLR_DROP_NOTIF:
   case MDFNNPCMD_CTRLR_DUPE_NOTIF:
			{
			 static const uint32 MaxNicknameLength = 1000;
			 static const uint32 MaxLength = 12 + MaxNicknameLength;
			 const char *fstr = NULL;
			 const uint32 len = raw_len;
			 uint8 ntf_buf[MaxLength + 1];
			 char *textbuf = NULL;

			 if(len < 12)
			  throw MDFN_Error(0, _("Take/drop/dupe notification is too short: %u"), len);

			 if(len > MaxLength)
			  throw MDFN_Error(0, _("Take/drop/dupe notification is too long: %u"), len);

			 MDFND_RecvData(ntf_buf, len);
			 ntf_buf[len] = 0;

 	 	 	 switch(cmd)
			 {
			  case MDFNNPCMD_CTRLR_TAKE_NOTIF:
			  	fstr = _("* <%s> took all instances of %s, and is now %s.");
				break;

			  case MDFNNPCMD_CTRLR_DUPE_NOTIF:
			 	fstr = _("* <%s> took copies of %s, and is now %s.");
				break;

			  case MDFNNPCMD_CTRLR_DROP_NOTIF:
				fstr = _("* <%s> dropped %s, and is now %s.");
				break;
			 }
                         trio_asprintf(&textbuf, fstr, ntf_buf + 12, GenerateMPSString(MDFN_de32lsb(&ntf_buf[0]), true).c_str(), GenerateMPSString(MDFN_de32lsb(&ntf_buf[4]), false).c_str());
	                 MDFND_NetplayText((UTF8*)textbuf, false);
			 free(textbuf);
			}
			break;

   case MDFNNPCMD_YOUJOINED:
   case MDFNNPCMD_YOULEFT:
   case MDFNNPCMD_PLAYERLEFT:
   case MDFNNPCMD_PLAYERJOINED:
			{
			 static const uint32 MaxLength = 2000;
                         uint8 neobuf[MaxLength + 1];
                         char *textbuf = NULL;
			 uint32 mps;
                         std::string mps_string;
			 const uint32 len = raw_len;

			 if(len < 8)
			 {
                          throw MDFN_Error(0, _("Join/Left length is too short: %u"), len);
		         }

                         if(len > MaxLength) // Sanity check
                         {
                          throw MDFN_Error(0, _("Join/Left length is too long: %u"), len);
                         }

                         MDFND_RecvData(neobuf, len);
			 neobuf[len] = 0; // NULL-terminate the string

			 mps = MDFN_de32lsb(&neobuf[0]);

			 mps_string = GenerateMPSString(mps);

			 if(cmd == MDFNNPCMD_YOULEFT)
			 {
			  // Uhm, not supported yet!
			  LocalPlayersMask = 0;
			  LocalInputStateSize = 0;
			  Joined = FALSE;
			 }
			 else if(cmd == MDFNNPCMD_YOUJOINED)
			 {
			  if(OurNick) // This shouldn't happen, really...
			  {
			   free(OurNick);
			   OurNick = NULL;
			  }
			  OurNick = strdup((char*)neobuf + 8);

                          trio_asprintf(&textbuf, _("* You, %s, have connected as: %s"), neobuf + 8, mps_string.c_str());

			  LocalPlayersMask = mps;
			  LocalInputStateSize = 0;
			  for(int x = 0; x < MDFNGameInfo->InputInfo->InputPorts; x++)
			  {
			   if(LocalPlayersMask & (1U << x))
			    LocalInputStateSize += PortLen[x];
			  }
			  Joined = TRUE;

			  SendCommand(MDFNNPCMD_SETFPS, MDFNGameInfo->fps);
			 }
			 else if(cmd == MDFNNPCMD_PLAYERLEFT)
			 {
                                  trio_asprintf(&textbuf, _("* %s(%s) has left"), neobuf + 8, mps_string.c_str());
			 }
			 else
			 {
                                  trio_asprintf(&textbuf, _("* %s has connected as: %s"), neobuf + 8, mps_string.c_str());
			 }
	                 MDFND_NetplayText((UTF8*)textbuf, FALSE);
			 free(textbuf);
			}
			break;
  }
}
예제 #23
0
bool MDFNI_LoadState(const char *fname, const char *suffix) noexcept
{
 bool ret = true;

 try
 {
  if(!MDFNGameInfo->StateAction)
  {
   throw MDFN_Error(0, _("Module \"%s\" doesn't support save states."), MDFNGameInfo->shortname);
  }

  /* For network play and movies, be load the state locally, and then save the state to a temporary buffer,
     and send or record that.  This ensures 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 ;)).
  */

  {
   GZFileStream st(fname ? std::string(fname) : MDFN_MakeFName(MDFNMKF_STATE,CurrentState,suffix), GZFileStream::MODE::READ);
   uint8 header[32];
   uint32 st_len;

   st.read(header, 32);

   st_len = MDFN_de32lsb(header + 16 + 4) & 0x7FFFFFFF;

   if(st_len < 32)
    throw MDFN_Error(0, _("Save state header length field is bad."));

   MemoryStream sm(st_len, -1);

   memcpy(sm.map(), header, 32);
   st.read(sm.map() + 32, st_len - 32);

   MDFNSS_LoadSM(&sm, false);
  }

  if(MDFNnetplay)
  {
   NetplaySendState();
  }

  if(MDFNMOV_IsRecording())
   MDFNMOV_RecordState();

  MDFND_SetStateStatus(NULL);

  if(!fname && !suffix)
  {
   SaveStateStatus[CurrentState] = true;
   MDFN_DispMessage(_("State %d loaded."), CurrentState);
  }
 }
 catch(std::exception &e)
 {
  if(!fname && !suffix)
   MDFN_DispMessage(_("State %d load error: %s"), CurrentState, e.what());
  else
   MDFN_PrintError("%s", e.what());

  if(MDFNnetplay)
   MDFND_NetplayText(e.what(), false);

  ret = false;
 }

 return(ret);
}
예제 #24
0
static void Emulate(EmulateSpecStruct *espec)
{
 //printf("%d\n", PCFX_V810.v810_timestamp);

 FXINPUT_Frame();

 MDFNMP_ApplyPeriodicCheats();

 if(espec->VideoFormatChanged)
  KING_SetPixelFormat(espec->surface->format); //.Rshift, espec->surface->format.Gshift, espec->surface->format.Bshift);

 if(espec->SoundFormatChanged)
  SoundBox_SetSoundRate(espec->SoundRate);


 KING_StartFrame(fx_vdc_chips, espec);	//espec->surface, &espec->DisplayRect, espec->LineWidths, espec->skip);

 v810_timestamp_t v810_timestamp;
 v810_timestamp = PCFX_V810.Run(pcfx_event_handler);


 PCFX_FixNonEvents();

 // Call before resetting v810_timestamp
 ForceEventUpdates(v810_timestamp);

 //
 // Call KING_EndFrame() before SoundBox_Flush(), otherwise CD-DA audio distortion will occur due to sound data being updated
 // after it was needed instead of before.
 //
 KING_EndFrame(v810_timestamp);

 //
 // new_base_ts is guaranteed to be <= v810_timestamp
 //
 v810_timestamp_t new_base_ts;
 espec->SoundBufSize = SoundBox_Flush(v810_timestamp, &new_base_ts, espec->SoundBuf, espec->SoundBufMaxSize);

 KING_ResetTS(new_base_ts);
 FXTIMER_ResetTS(new_base_ts);
 FXINPUT_ResetTS(new_base_ts);
 SoundBox_ResetTS(new_base_ts);

 // Call this AFTER all the EndFrame/Flush/ResetTS stuff
 RebaseTS(v810_timestamp, new_base_ts);

 espec->MasterCycles = v810_timestamp - new_base_ts;

 PCFX_V810.ResetTS(new_base_ts);

 //
 //
 //
 if(BackupSignalDirty)
 {
  BackupSaveDelay = 120;
  BackupSignalDirty = false;
 }
 else if(BackupSaveDelay)
 {
  BackupSaveDelay--;

  if(!BackupSaveDelay)
  {
   //puts("SAVE");
   try
   {
    SaveBackupMemory();
   }
   catch(std::exception &e)
   {
    MDFN_PrintError(_("Error saving save-game memory: %s"), e.what());
    MDFN_DispMessage(_("Error saving save-game memory: %s"), e.what());
    BackupSaveDelay = 60 * 60;	// Try it again in about 60 seconds emulated time(unless more writes occur to the backup memory before then, then the regular delay
				// will be used from that time).
   }
  }
 }
}