// Called after a game is loaded.
bool MemDebugger_Init(void)
{
 if(CurGame->Debugger)
 {
  AddressSpaces = CurGame->Debugger->AddressSpaces;

  CurASpace = 0;
  ASpace = &(*AddressSpaces)[CurASpace];

  size_t num = AddressSpaces->size();

  ASpacePos = (uint32 *)calloc(sizeof(uint32), num);
  SizeCache = (uint64 *)calloc(sizeof(uint64), num);
  GoGoPowerDD = (uint64 *)calloc(sizeof(uint64), num);

  for(size_t i = 0; i < num; i++)
  {
   uint64 tmpsize;

   tmpsize = (*AddressSpaces)[i].NP2Size;

   if(!tmpsize)
    tmpsize = (uint64)1 << (*AddressSpaces)[i].TotalBits;

   SizeCache[i] = tmpsize;
  }

  ICV_Init( MDFN_GetSettingS(std::string(std::string(CurGame->shortname) + "." + std::string("debugger.memcharenc")).c_str()).c_str() );
 }
 else
  AddressSpaces = NULL;
 return(TRUE);
}
Example #2
0
void MDFN_StateEvilBegin(void)
{
 int x;
 std::string srwcompstring;

 if(!EvilEnabled)
  return;

 SRW_NUM = (int)MDFN_GetSettingUI("srwframes");

 SRWCompressor = SRW_COMPRESSOR_MINILZO;
 srwcompstring = MDFN_GetSettingS("srwcompressor");

 if(srwcompstring == "minilzo")
  SRWCompressor = SRW_COMPRESSOR_MINILZO;
 else if(srwcompstring == "quicklz")
  SRWCompressor  = SRW_COMPRESSOR_QUICKLZ;
 else if(srwcompstring == "blz")
  SRWCompressor = SRW_COMPRESSOR_BLZ;

 bcs = (StateMemPacket *)calloc(SRW_NUM, sizeof(StateMemPacket));
 bcspos = 0;

 for(x=0;x<SRW_NUM;x++)
 {
  bcs[x].data = NULL;
  bcs[x].compressed_len = 0;
  bcs[x].uncompressed_len = 0;
  memset(&bcs[x].MovieLove, 0, sizeof(StateMem));
 }
}
Example #3
0
bool MDFNI_StartAVRecord(const char *path, double SoundRate)
{
 try
 {
  QTRecord::VideoSpec spec;

  memset(&spec, 0, sizeof(spec));

  spec.SoundRate = SoundRate;
  spec.SoundChan = MDFNGameInfo->soundchan;
  spec.VideoWidth = MDFNGameInfo->lcm_width;
  spec.VideoHeight = MDFNGameInfo->lcm_height;
  spec.VideoCodec = MDFN_GetSettingI("qtrecord.vcodec");
  spec.MasterClock = MDFNGameInfo->MasterClock;

  if(spec.VideoWidth < MDFN_GetSettingUI("qtrecord.w_double_threshold"))
   spec.VideoWidth *= 2;

  if(spec.VideoHeight < MDFN_GetSettingUI("qtrecord.h_double_threshold"))
   spec.VideoHeight *= 2;


  spec.AspectXAdjust = ((double)MDFNGameInfo->nominal_width * 2) / spec.VideoWidth;
  spec.AspectYAdjust = ((double)MDFNGameInfo->nominal_height * 2) / spec.VideoHeight;

  MDFN_printf("\n");
  MDFN_printf(_("Starting QuickTime recording to file \"%s\":\n"), path);
  MDFN_indent(1);
  MDFN_printf(_("Video width: %u\n"), spec.VideoWidth);
  MDFN_printf(_("Video height: %u\n"), spec.VideoHeight);
  MDFN_printf(_("Video codec: %s\n"), MDFN_GetSettingS("qtrecord.vcodec").c_str());

  if(spec.SoundRate && spec.SoundChan)
  {
   MDFN_printf(_("Sound rate: %u\n"), std::min<uint32>(spec.SoundRate, 64000));
   MDFN_printf(_("Sound channels: %u\n"), spec.SoundChan);
  }
  else
   MDFN_printf(_("Sound: Disabled\n"));

  MDFN_indent(-1);
  MDFN_printf("\n");

  qtrecorder = new QTRecord(path, spec);
 }
 catch(std::exception &e)
 {
  MDFND_PrintError(e.what());
  return(false);
 }
 return(true);
}
Example #4
0
static std::string			GetFile					()
{
    if(FileChooser == 0)
    {
        FileChooser = new FileSelect(_("Select ROM"), MDFN_GetSettingS("es.bookmarks"), "", new SummerfaceStaticConduit(FileBrowserHook, (void*)0));
    }

    std::string result = FileChooser->GetFile();

    std::string bookmarks;
    MDFNI_SetSetting("es.bookmarks", FileChooser->GetBookmarks(bookmarks).c_str());

    return result;
}
Example #5
0
static int LoadCD(std::vector<CDIF *> *CDInterfaces)
{
 std::string bios_path = MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, MDFN_GetSettingS("pce_fast.cdbios").c_str() );

 //IsHES = 0;
 IsSGX = 0;

 LoadCommonPre();

 if(!HuCLoadCD(bios_path.c_str()))
  return(0);

 SCSICD_SetDisc(true, NULL, true);
 SCSICD_SetDisc(false, (*CDInterfaces)[0], true);

 return(LoadCommon());
}
Example #6
0
// Called from game thread
int MDFND_NetworkConnect(void)
{
 std::string remote_host = MDFN_GetSettingS("netplay.host");
 unsigned int remote_port = MDFN_GetSettingUI("netplay.port");

 if(Connection)
 {
  MDFND_NetworkClose();
 }

 try
 {
  #ifdef HAVE_POSIX_SOCKETS
  Connection = new NetClient_POSIX();
  #elif defined(WIN32)
  Connection = new NetClient_WS2();
  #else
  throw MDFN_Error(0, _("Networking system API support not compiled in."));
  #endif
  Connection->Connect(remote_host.c_str(), remote_port);
 }
 catch(std::exception &e)
 {
  PrintNetError("%s", e.what());
  return(0);
 }

 PrintNetStatus(_("*** Sending initialization data to server."));

 MDFNDnetplay = 1;
 if(!MDFNI_NetplayStart())
 {
  MDFNDnetplay = 0;
  return(0);
 }
 PrintNetStatus(_("*** Connection established."));

 return(1);
}
Example #7
0
static MDFN_COLD void LoadCD(std::vector<CDIF *> *CDInterfaces)
{
 try
 {
	 std::string bios_path = MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, MDFN_GetSettingS("pce_fast.cdbios"));

	 //IsHES = 0;
	 IsSGX = 0;

	 LoadCommonPre();

	 HuC_LoadCD(bios_path.c_str());

	 cdifs = CDInterfaces;
	 PCECD_Drive_SetDisc(true, NULL, true);

	 LoadCommon();
 }
 catch(...)
 {
	 Cleanup();
	 throw;
 }
}
Example #8
0
	static int								ModuleLoad				()
	{
		//Load the BIOS
		MDFNFILE biosFile;
		if(biosFile.Open(MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, MDFN_GetSettingS("pcsxr.bios").c_str()).c_str(), 0))
		{
			if(biosFile.size == 512 * 1024)
			{
				memcpy(BiosBuffer, biosFile.data, 512 * 1024);
			}
			else
			{
				MDFN_printf("pcsxr: BIOS file size incorrect\n");
			}
		}
		else
		{
			MDFN_printf("pcsxr: Failed to load bios\n");
			return 0;
		}
	
		//Setup the config structure
		memset(&Config, 0, sizeof(Config));
		Config.PsxAuto = 1;
		Config.Cpu = MDFN_GetSettingB("pcsxr.recompiler") ? CPU_DYNAREC : CPU_INTERPRETER;
		Config.SlowBoot = MDFN_GetSettingB("pcsxr.slowboot");
		strcpy(Config.PluginsDir, "builtin");
		strcpy(Config.Gpu, "builtin");
		strcpy(Config.Spu, "builtin");
		strcpy(Config.Pad1, "builtin");
		strcpy(Config.Pad2, "builtin");
		strcpy(Config.Cdr, "builtin");
		strcpy(Config.Net, "Disabled");
		strncpy(Config.Mcd1, MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), MAXPATHLEN);
		strncpy(Config.Mcd2, MDFN_MakeFName(MDFNMKF_SAV, 0, "sav2").c_str(), MAXPATHLEN);

		//Init psx cpu emulator and memory mapping
		EmuInit();

		//Open and initialize all of the plugins
		OpenPlugins();

		//Load memory cards
		LoadMcds(Config.Mcd1, Config.Mcd2);

		//Get cdrom ID and init PPF support...
		CheckCdrom();

		//Reset the emulated CPU and Memory
		EmuReset();

		//Prepares the game to run, either runs the CPU thru the bios or finds and loads the game EXE if using the emulated bios
		LoadCdrom();

		//TODO: Set the clock if the machine is PAL

		//Just say two 1M pages, for fun not profit
		MDFNMP_Init(1024 * 1024, 2);
		MDFNMP_AddRAM(1024 * 1024 * 2, 0, (uint8_t*)psxM);

		return 1;
	}
Example #9
0
bool Sound_Init(MDFNGI *gi)
{
 SexyAL_DriverInfo CurDriver;

 NeedReInit = false;
 SoundRate = 0;

 memset(&format, 0, sizeof(format));
 memset(&buffering, 0, sizeof(buffering));

 Interface = new SexyAL();

 format.sampformat = SEXYAL_FMT_PCMS16;

 assert(gi->soundchan);
 format.channels = gi->soundchan;

 format.revbyteorder = 0;
 format.noninterleaved = false;
 format.rate = gi->soundrate ? gi->soundrate : MDFN_GetSettingUI("sound.rate");

 buffering.ms = MDFN_GetSettingUI("sound.buffer_time");

 if(!buffering.ms)
 {
  buffering.overhead_kludge = true;
  buffering.ms = 7 + floor(0.5 + 1.5 * 1000.0 / gi->fps * (256 * 65536));
 }
 else
  buffering.overhead_kludge = false;

 buffering.period_us = MDFN_GetSettingUI("sound.period_time");

 std::string zedevice = MDFN_GetSettingS("sound.device");
 std::string zedriver = MDFN_GetSettingS("sound.driver");

 MDFNI_printf(_("\nInitializing sound...\n"));
 MDFN_indent(1);

 if(!Interface->FindDriver(&CurDriver, zedriver.c_str()))
 {
  std::vector<SexyAL_DriverInfo> DriverTypes = Interface->GetDriverList();

  MDFN_printf(_("\nUnknown sound driver \"%s\".  Compiled-in sound drivers:\n"), zedriver.c_str());

  MDFN_indent(2);
  for(unsigned x = 0; x < DriverTypes.size(); x++)
  {
   MDFN_printf("%s\n", DriverTypes[x].short_name);
  }
  MDFN_indent(-2);
  MDFN_printf("\n");

  delete Interface;
  Interface = NULL;

  MDFN_indent(-1);
  return(FALSE);
 }

 if(!strcasecmp(zedevice.c_str(), "default"))
  MDFNI_printf(_("Using \"%s\" audio driver with SexyAL's default device selection."), CurDriver.name);
 else
  MDFNI_printf(_("Using \"%s\" audio driver with device \"%s\":"), CurDriver.name, zedevice.c_str());
 MDFN_indent(1);

 //RunSexyALTest(Interface, &buffering, zedevice.c_str(), CurDriver.type);
 //exit(1);
 if(!(Output=Interface->Open(zedevice.c_str(), &format, &buffering, CurDriver.type)))
 {
  MDFND_PrintError(_("Error opening a sound device."));

  delete Interface;
  Interface = NULL;
  MDFN_indent(-2);
  return(FALSE);
 }

 if(format.rate < 22050 || format.rate > 192000)
 {
  MDFND_PrintError(_("Set rate is out of range [22050-192000]"));
  Sound_Kill();
  MDFN_indent(-2);
  return(FALSE);
 }
 MDFNI_printf(_("\nBits: %u%s\nRate: %u\nChannels: %u%s\nByte order: CPU %s\nBuffer size: %u sample frames(%f ms)\n"), (format.sampformat>>4)*8, (format.sampformat == SEXYAL_FMT_PCMFLOAT) ? _(" (floating-point)") : "",format.rate,format.channels,format.noninterleaved ? _(" (non-interleaved) ") : "", format.revbyteorder?"Reversed":"Native", buffering.buffer_size, (double)buffering.buffer_size * 1000 / format.rate);
 MDFNI_printf(_("Latency: %u sample frames(%f ms)\n"), buffering.latency, (double)buffering.latency * 1000 / format.rate);

 if(buffering.period_size)
 {
  //int64_t pt_test_result = ((int64_t)buffering.period_size * (1000 * 1000) / format.rate);
  int64_t bt_test_result = ((int64_t)(buffering.bt_gran ? buffering.bt_gran : buffering.period_size) * (1000 * 1000) / format.rate);
  MDFNI_printf(_("Period size: %u sample frames(%f ms)\n"), buffering.period_size, (double)buffering.period_size * 1000 / format.rate);

  if(bt_test_result > 5333)
  {
   MDFN_indent(1);

   if(!buffering.bt_gran)
    MDFN_printf(_("Warning: Period time is too large(it should be <= ~5.333ms).  Video will appear very jerky.\n"));
   else
    MDFN_printf(_("Warning: Buffer update timing granularity is too large(%f; it should be <= ~5.333ms).  Video will appear very jerky.\n"), (double)buffering.bt_gran * 1000 / format.rate);
   MDFN_indent(-1);
  }
 }

 format.sampformat = SEXYAL_FMT_PCMS16;
 format.channels = gi->soundchan?gi->soundchan:1;
 format.revbyteorder = 0;
 format.noninterleaved = false;
 //format.rate=gi->soundrate?gi->soundrate:soundrate;

 Output->SetConvert(Output, &format);

 EmuModBufferSize = (500 * format.rate + 999) / 1000;
 EmuModBuffer = (int16 *)calloc(sizeof(int16) * format.channels, EmuModBufferSize);

 SoundRate = format.rate;
 MDFN_indent(-2);

 return(1);
}
Example #10
0
static void ParseSTDIOCommand(char *buf)
{
 char *arguments[8];
 int which_argument = 0;
 size_t blen = strlen(buf);
 bool InQuote = 0;
 char *InBegin = NULL;
 char last_char = 0;

 memset(arguments, 0, sizeof(arguments));

 for(size_t x = 0; x <= blen; x++)
 {
  if((buf[x] == ' ' || buf[x] == 0) && last_char != '\\' && !InQuote && InBegin)
  {
   buf[x] = 0;

   unescape_string(InBegin);
   arguments[which_argument] = InBegin;
   which_argument++;
   if(which_argument == 8)
   {
    break;
   }
   InBegin = NULL;
  }
  else if(buf[x] != ' ' && buf[x] != '\t' && buf[x] != '"' && last_char != '\\' && !InQuote && !InBegin)
  {
   InBegin = &buf[x];
  }
  else if(buf[x] == '"' && last_char != '\\')
  {
   if(InBegin)
   {
    buf[x] = 0;
    unescape_string(InBegin);
    arguments[which_argument] = InBegin;
    which_argument++;
    if(which_argument == 8)
    {
     break;
    }
    InQuote = 0;
    InBegin = NULL;
   }
   else
   {
    InQuote = TRUE;
    InBegin = &buf[x + 1];
   }
  }
  last_char = buf[x];
 }

 int numargs = which_argument; // numargs count includes the command.  Misleading, yes!
 bool success = 0;
 bool suppress_success = 0;

 if(numargs)
 {
  if(!strcasecmp(arguments[0], "exit"))
  {
   MainRequestExit();
   suppress_success = TRUE;
  }
  else if(!strcasecmp(arguments[0], "nop"))
  {
   success = true;
  }
  else if(!strcasecmp(arguments[0], "sync_video"))
  {
   success = GT_ReinitVideo();
  }
  else if(!strcasecmp(arguments[0], "sync_sound"))
  {
   success = GT_ReinitSound();
  }
  else if(!strcasecmp(arguments[0], "get_setting"))
  {
   if(numargs == 2)
   {
    std::string sval;

    sval = MDFN_GetSettingS(arguments[1]);
    success = TRUE;

    Remote_SendCommand("return", 2, "success", sval.c_str());
    return;
   }
   else
    puts("Invalid number of arguments");
  }
  else if(!strcasecmp(arguments[0], "set_setting"))
  {
   if(numargs == 3)
   {
    success = MDFNI_SetSetting(arguments[1], arguments[2]);
   }
   else
    puts("Invalid number of arguments");
  }
  else if(!strcasecmp(arguments[0], "get_known_fileexts"))
  {
   uint32 count = 0;
   char count_string[64];

   // TODO:  Move to core
   for(unsigned int i = 0; i < MDFNSystems.size(); i++)
   {
    const FileExtensionSpecStruct *FileExtensions = MDFNSystems[i]->FileExtensions;
    if(FileExtensions)
     while(FileExtensions->extension)
     {
      count++;
      FileExtensions++;
     }
   }
   trio_snprintf(count_string, 64, "%u", count);
   Remote_SendCommand("result_count", 1, count_string);

   for(unsigned int i = 0; i < MDFNSystems.size(); i++)
   {
    const FileExtensionSpecStruct *FileExtensions = MDFNSystems[i]->FileExtensions;
    if(FileExtensions)
     while(FileExtensions->extension)
     {
      Remote_SendCommand("result", 3, MDFNSystems[i]->shortname, FileExtensions->extension, FileExtensions->description);
      FileExtensions++;
     }
   }
   success = TRUE;
  }
  else
  {
   puts("Unknown command!");
  }
 }

 if(!suppress_success)
 {
  if(success)
  {
   Remote_SendCommand("return", 1, "success");
  }
  else
  {
   Remote_SendCommand("return", 1, "failure");
  }
 }
 //printf("%s %s %s %s %s %s\n", arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
}
Example #11
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string& Settings::getString(const string& key) const
{
  static string result = MDFN_GetSettingS((std::string("stella.") + key).c_str());
  return result;
}
Example #12
0
int NetplayStart(const char *PortDeviceCache[16], const uint32 PortDataLenCache[16])
{
 try
 {
  const char *emu_id = PACKAGE " " MEDNAFEN_VERSION;
  const uint32 local_players = MDFN_GetSettingUI("netplay.localplayers");
  const std::string nickname = MDFN_GetSettingS("netplay.nick");
  const std::string game_key = MDFN_GetSettingS("netplay.gamekey");
  const std::string connect_password = MDFN_GetSettingS("netplay.password");
  login_data_t *ld = NULL;
  std::vector<uint8> sendbuf;

  MDFNnetplay = true;

  sendbuf.resize(4 + sizeof(login_data_t) + nickname.size() + strlen(emu_id));

  MDFN_en32lsb(&sendbuf[0], sendbuf.size() - 4);
  ld = (login_data_t*)&sendbuf[4];

  if(game_key != "")
  {
   md5_context md5;
   uint8 md5out[16];

   md5.starts();
   md5.update(MDFNGameInfo->MD5, 16);
   md5.update((uint8 *)game_key.c_str(), game_key.size());
   md5.finish(md5out);
   memcpy(ld->gameid, md5out, 16);
  }
  else
   memcpy(ld->gameid, MDFNGameInfo->MD5, 16);

  if(connect_password != "")
  {
   md5_context md5;
   uint8 md5out[16];

   md5.starts();
   md5.update((uint8*)connect_password.c_str(), connect_password.size());
   md5.finish(md5out);
   memcpy(ld->password, md5out, 16);
  }

  assert(MDFNGameInfo->InputInfo->InputPorts <= 16);

  ld->protocol_version = 3;

  // Set input device number thingies here.
  ld->total_controllers = MDFNGameInfo->InputInfo->InputPorts; // Total number of ports

  MDFN_en32lsb(ld->emu_name_len, strlen(emu_id));

  // Controller data sizes.
  for(int x = 0; x < MDFNGameInfo->InputInfo->InputPorts; x++)
   ld->controller_data_size[x] = PortDataLenCache[x];

  // Controller types
  for(int x = 0; x < MDFNGameInfo->InputInfo->InputPorts; x++)
  {
   unsigned ct = 0;

   for(int d = 0; d < MDFNGameInfo->InputInfo->Types[x].NumTypes; d++)
   {
    if(!strcasecmp(MDFNGameInfo->InputInfo->Types[x].DeviceInfo[d].ShortName, PortDeviceCache[x]))
    {
     ct = d;
     break;
    }
   }
   //printf("%d, 0x%02x\n", x, ct);

   ld->controller_type[x] = ct;
  }

  ld->local_players = local_players;

  if(nickname != "")
   memcpy(&sendbuf[4 + sizeof(login_data_t)], nickname.c_str(), nickname.size());

  memcpy(&sendbuf[4 + sizeof(login_data_t) + nickname.size()], emu_id, strlen(emu_id));

  MDFND_SendData(&sendbuf[0], sendbuf.size());

  TotalInputStateSize = 0;
  for(int x = 0; x < MDFNGameInfo->InputInfo->InputPorts; x++)
    TotalInputStateSize += PortDataLenCache[x];

  // Hack so the server can always encode its command data length properly(a matching "hack" exists in the server).
  if(TotalInputStateSize < 4)
   TotalInputStateSize = 4;

  TotalInputStateSize = TotalInputStateSize;

  LocalPlayersMask = 0;
  LocalInputStateSize = 0; 
  Joined = false;

  //
  //
  //
  MDFN_FlushGameCheats(0);	/* Save our pre-netplay cheats. */

  if(MDFNMOV_IsPlaying())		/* Recording's ok during netplay, playback is not. */
   MDFNMOV_Stop();
 }
 catch(std::exception &e)
 {
  NetError("%s", e.what());
  return(false);
 }

 //printf("%d\n", TotalInputStateSize);

 return(1);
}
Example #13
0
bool InitSound(MDFNGI *gi)
{
 SoundRate = 0;

 memset(&format,0,sizeof(format));
 memset(&buffering,0,sizeof(buffering));

 Interface = (SexyAL *)SexyAL_Init(0);
 DriverTypes = Interface->EnumerateTypes(Interface);

 format.sampformat = SEXYAL_FMT_PCMS16;

 assert(gi->soundchan);
 format.channels = gi->soundchan;

 format.revbyteorder = 0;

 format.rate = gi->soundrate ? gi->soundrate : MDFN_GetSettingUI("sound.rate");

 buffering.ms = MDFN_GetSettingUI("sound.buffer_time");
 buffering.period_us = MDFN_GetSettingUI("sound.period_time");

 std::string zedevice = MDFN_GetSettingS("sound.device");
 std::string zedriver = MDFN_GetSettingS("sound.driver");

 CurDriverIndex = -1;

 if(!strcasecmp(zedriver.c_str(), "default"))
  CurDriverIndex = 0;
 else
 {
  for(int x = 0; DriverTypes[x].short_name; x++)
  {
   if(!strcasecmp(zedriver.c_str(), DriverTypes[x].short_name))
   {
    CurDriverIndex = x;
    break;
   }
  }
 }

 MDFNI_printf(_("\nInitializing sound...\n"));
 MDFN_indent(1);

 if(CurDriverIndex == -1)
 {
  MDFN_printf(_("\nUnknown sound driver \"%s\".  Supported sound drivers:\n"), zedriver.c_str());

  MDFN_indent(2);
  for(int x = 0; DriverTypes[x].short_name; x++)
  {
   MDFN_printf("%s\n", DriverTypes[x].short_name);
  }
  MDFN_indent(-2);
  MDFN_printf("\n");
  Interface->Destroy(Interface);
  Interface = NULL;
  MDFN_indent(-1);
  return(FALSE);
 }

 MDFNI_printf(_("Using \"%s\" audio driver with device \"%s\":"),DriverTypes[CurDriverIndex].name, zedevice.c_str());
 MDFN_indent(1);

 //RunSexyALTest(Interface, &buffering, zedevice.c_str(), DriverTypes[CurDriverIndex].type);
 //exit(1);

 if(!(Output=Interface->Open(Interface, zedevice.c_str(), &format, &buffering, DriverTypes[CurDriverIndex].type)))
 {
  MDFND_PrintError(_("Error opening a sound device."));
  Interface->Destroy(Interface);
  Interface=0;
  MDFN_indent(-2);
  return(FALSE);
 }

 if(format.rate<8192 || format.rate > 48000)
 {
  MDFND_PrintError(_("Set rate is out of range [8192-48000]"));
  KillSound();
  MDFN_indent(-2);
  return(FALSE);
 }
 MDFNI_printf(_("\nBits: %u\nRate: %u\nChannels: %u\nByte order: CPU %s\nBuffer size: %u sample frames(%f ms)\n"), (format.sampformat>>4)*8,format.rate,format.channels,format.revbyteorder?"Reversed":"Native", buffering.buffer_size, (double)buffering.buffer_size * 1000 / format.rate);
 MDFNI_printf(_("Latency: %u sample frames(%f ms)\n"), buffering.latency, (double)buffering.latency * 1000 / format.rate);

 if(buffering.period_size)
 {
  int64_t pt_test_result = ((int64_t)buffering.period_size * (1000 * 1000) / format.rate);

  MDFNI_printf(_("Period size: %u sample frames(%f ms)\n"), buffering.period_size, (double)buffering.period_size * 1000 / format.rate);

  if(pt_test_result > 5333)
  {
   MDFN_indent(1);
   MDFN_printf(_("Warning: Period time is too large(it should be <= ~5.333ms).  Video will appear very jerky.\n"));
   MDFN_indent(-1);
  }
 }
 format.sampformat=SEXYAL_FMT_PCMS16;
 format.channels=gi->soundchan?gi->soundchan:1;
 format.revbyteorder=0;

 //format.rate=gi->soundrate?gi->soundrate:soundrate;

 Output->SetConvert(Output, &format);

 EmuModBufferSize = (500 * format.rate + 999) / 1000;
 EmuModBuffer = (int16 *)calloc(sizeof(int16) * format.channels, EmuModBufferSize);

 SoundRate = format.rate;
 MDFN_indent(-2);

 return(1);
}