Пример #1
0
JoystickDriver_DX5::JoystickDriver_DX5(bool exclude_xinput) : dii(NULL)
{
 enum_device_list edl;
 std::set<uint32> exclude_vps;

 try
 {
  REQUIRE_DI_CALL( DirectInputCreate(GetModuleHandle(NULL), DIRECTINPUT_VERSION, &dii, NULL) );
  REQUIRE_DI_CALL( dii->EnumDevices(DIDEVTYPE_JOYSTICK, GLOB_EnumJoysticksProc, &edl, DIEDFL_ATTACHEDONLY) );

  if(exclude_xinput)
  {
   exclude_vps = GetXInputVidPid();
  }

  for(unsigned i = 0; i < edl.valid_count; i++)
  {
   Joystick_DX5 *jdx5 = NULL;

   if(edl.ddi[i].guidProduct.Data1 && exclude_vps.count(edl.ddi[i].guidProduct.Data1))
    continue;

   try
   {
    jdx5 = new Joystick_DX5(dii, &edl.ddi[i]);
    joys.push_back(jdx5);
   }
   catch(std::exception &e)
   {
    MDFND_PrintError(e.what());
    if(jdx5 != NULL)
    {
     delete jdx5;
     jdx5 = NULL;
    }
   }
  }
 }
 catch(std::exception &e)
 {
  MDFND_PrintError(e.what());
 }
}
Пример #2
0
WAVRecord::~WAVRecord()
{
 try
 {
  Finish();
 }
 catch(std::exception &e)
 {
  MDFND_PrintError(e.what());
 }
}
Пример #3
0
FileStream::~FileStream()
{
 try
 {
  close();
 }
 catch(std::exception &e)
 {
  MDFND_PrintError(e.what());
 }
}
Пример #4
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);
}
Пример #5
0
bool MDFNI_StartWAVRecord(const char *path, double SoundRate)
{
    try
    {
        wavrecorder = new WAVRecord(path, SoundRate, MDFNGameInfo->soundchan);
    }
    catch(std::exception &e)
    {
        MDFND_PrintError(e.what());
        return(false);
    }

    return(true);
}
Пример #6
0
void MDFN_PrintError(const char *format, ...)
{
 char *temp;

 va_list ap;

 va_start(ap, format);

 temp = trio_vaprintf(format, ap);
 MDFND_PrintError(temp);
 free(temp);

 va_end(ap);
}
Пример #7
0
void MDFN_PrintError(const char *format, ...)
{
 char *temp;

 va_list ap;

 va_start(ap, format);

 temp = new char[4096];
 vsnprintf(temp, 4096, format, ap);
 MDFND_PrintError(temp);
 free(temp);

 va_end(ap);
}
Пример #8
0
static bool RunSexyALTest(SexyAL *interface, SexyAL_buffering *buffering, const char *device, int driver_type)
{
 static const int to_format[9] = 
 {
  SEXYAL_FMT_PCMU8,
  SEXYAL_FMT_PCMS8,
  SEXYAL_FMT_PCMU16,
  SEXYAL_FMT_PCMS16,

  SEXYAL_FMT_PCMU24,
  SEXYAL_FMT_PCMS24,
  SEXYAL_FMT_PCMU32,
  SEXYAL_FMT_PCMS32,

  SEXYAL_FMT_PCMFLOAT
 };

 static const char *to_format_name[9] = 
 {
  "8-bit unsigned",
  "8-bit signed",
  "16-bit unsigned",
  "16-bit signed",
  "24-bit unsigned",
  "24-bit signed",
  "32-bit unsigned",
  "32-bit signed",
  "float"
 };

 // TODO: byte order format conversion.
 // TODO: source format.
 const int rate = 48000;
 const int numframes = (rate / 2 + 1) &~ 1;

 for(int src_channels = 1; src_channels <= 2; src_channels++)
 {
  for(int dest_channels = 1; dest_channels <= 2; dest_channels++)
  {
   //for(int src_format = 0; src_format < 9; src_format++)
   int src_format = 3;
   {
    for(int dest_format = 0; dest_format < 9; dest_format++)
    {
     printf("Source Format: %s, Source Channels: %d --- Dest Format: %s, Dest Channels: %d\n\n", to_format_name[src_format], src_channels, to_format_name[dest_format], dest_channels);

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

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

     format.sampformat = to_format[dest_format];
     format.channels = dest_channels;
     format.revbyteorder = 0;
     format.rate = rate;

     buffering->buffer_size = 0;
     buffering->period_size = 0;
     buffering->latency = 0;
     buffering->bt_gran = 0;

     if(!(Output=Interface->Open(Interface, device, &format, buffering, driver_type)))
     {
      MDFND_PrintError(_("Error opening a sound device."));
      Interface->Destroy(Interface);
      Interface=0;
      return(0);
     }

     if(format.sampformat != to_format[dest_format])
      printf("Warning: Could not set desired device format.\n");

     if(format.channels != dest_channels)
      printf("Warning: Could not set desired device channel count.\n");

     if(format.rate != rate)
      printf("Warning: Could not set desired device rate.\n");

     format.sampformat = to_format[src_format];
     format.channels = src_channels;
     format.revbyteorder = 0;
     format.rate = rate;

     Output->SetConvert(Output, &format);

     if(to_format[src_format] == SEXYAL_FMT_PCMS16)
     {
      int16 samples[numframes * src_channels];

      for(int i = 0; i < numframes; i++)
      {
       int16 sval = 4095 * sin((double)i * 440 * M_PI * 2 / rate);
       
       for(int ch = 0; ch < src_channels; ch++)
        samples[i * src_channels + ch] = sval;
      }
      // Write half in one go, the rest in small chunks.
      if(!Output->Write(Output, samples, numframes / 2))
	printf("Write count error 0\n");

      for(int i = numframes / 2; i < numframes; i += 100)
      {
       int32 towrite = numframes - i;
 
       if(towrite > 100)
        towrite = 100;

       if(!Output->Write(Output, samples + i * src_channels, towrite))
        printf("Write count error 1\n");
      }
     }
     Output->Close(Output);
     Interface->Destroy(Interface);
     sleep(1);
    }
   }
  }
 }
}
Пример #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);
}
Пример #10
0
bool MDFNI_InitializeModules(const std::vector<MDFNGI *> &ExternalSystems)
{
    static MDFNGI *InternalSystems[] =
    {
#ifdef WANT_NES_EMU
        &EmulatedNES,
#endif

#ifdef WANT_SNES_EMU
        &EmulatedSNES,
#endif

#ifdef WANT_GB_EMU
        &EmulatedGB,
#endif

#ifdef WANT_GBA_EMU
        &EmulatedGBA,
#endif

#ifdef WANT_PCE_EMU
        &EmulatedPCE,
#endif

#ifdef WANT_PCE_FAST_EMU
        &EmulatedPCE_Fast,
#endif

#ifdef WANT_LYNX_EMU
        &EmulatedLynx,
#endif

#ifdef WANT_MD_EMU
        &EmulatedMD,
#endif

#ifdef WANT_PCFX_EMU
        &EmulatedPCFX,
#endif

#ifdef WANT_NGP_EMU
        &EmulatedNGP,
#endif

#ifdef WANT_PSX_EMU
        &EmulatedPSX,
#endif

#ifdef WANT_VB_EMU
        &EmulatedVB,
#endif

#ifdef WANT_WSWAN_EMU
        &EmulatedWSwan,
#endif

#ifdef WANT_SMS_EMU
        &EmulatedSMS,
        &EmulatedGG,
#endif

        &EmulatedCDPlay
    };
    std::string i_modules_string, e_modules_string;

    for(unsigned int i = 0; i < sizeof(InternalSystems) / sizeof(MDFNGI *); i++)
    {
        AddSystem(InternalSystems[i]);
        if(i)
            i_modules_string += " ";
        i_modules_string += std::string(InternalSystems[i]->shortname);
    }

    for(unsigned int i = 0; i < ExternalSystems.size(); i++)
    {
        AddSystem(ExternalSystems[i]);
        if(i)
            i_modules_string += " ";
        e_modules_string += std::string(ExternalSystems[i]->shortname);
    }

    MDFNI_printf(_("Internal emulation modules: %s\n"), i_modules_string.c_str());
    MDFNI_printf(_("External emulation modules: %s\n"), e_modules_string.c_str());


    for(unsigned int i = 0; i < MDFNSystems.size(); i++)
        MDFNSystemsPrio.push_back(MDFNSystems[i]);

    MDFNSystemsPrio.sort(MDFNSystemsPrio_CompareFunc);

#if 0
    std::string a_modules;

std::list<MDFNGI *>:
    iterator it;

    for(it = MDFNSystemsPrio.
             f
#endif

             CDUtility::CDUtility_Init();

            return(1);
}

int MDFNI_Initialize(const char *basedir, const std::vector<MDFNSetting> &DriverSettings)
{
    // FIXME static
    static std::vector<MDFNSetting> dynamic_settings;

    if(!MDFN_RunMathTests())
    {
        return(0);
    }


    memset(PortDataCache, 0, sizeof(PortDataCache));
    memset(PortDataLenCache, 0, sizeof(PortDataLenCache));
    memset(PortDeviceCache, 0, sizeof(PortDeviceCache));

    lzo_init();

    MDFNI_SetBaseDirectory(basedir);

    MDFN_InitFontData();

    // Generate dynamic settings
    for(unsigned int i = 0; i < MDFNSystems.size(); i++)
    {
        MDFNSetting setting;
        const char *sysname;

        sysname = (const char *)MDFNSystems[i]->shortname;

        if(!MDFNSystems[i]->soundchan)
            printf("0 sound channels for %s????\n", sysname);

        if(MDFNSystems[i]->soundchan == 2)
        {
            BuildDynamicSetting(&setting, sysname, "forcemono", MDFNSF_COMMON_TEMPLATE | MDFNSF_CAT_SOUND, CSD_forcemono, MDFNST_BOOL, "0");
            dynamic_settings.push_back(setting);
        }

        BuildDynamicSetting(&setting, sysname, "enable", MDFNSF_COMMON_TEMPLATE, CSD_enable, MDFNST_BOOL, "1");
        dynamic_settings.push_back(setting);

        BuildDynamicSetting(&setting, sysname, "tblur", MDFNSF_COMMON_TEMPLATE | MDFNSF_CAT_VIDEO, CSD_tblur, MDFNST_BOOL, "0");
        dynamic_settings.push_back(setting);

        BuildDynamicSetting(&setting, sysname, "tblur.accum", MDFNSF_COMMON_TEMPLATE | MDFNSF_CAT_VIDEO, CSD_tblur_accum, MDFNST_BOOL, "0");
        dynamic_settings.push_back(setting);

        BuildDynamicSetting(&setting, sysname, "tblur.accum.amount", MDFNSF_COMMON_TEMPLATE | MDFNSF_CAT_VIDEO, CSD_tblur_accum_amount, MDFNST_FLOAT, "50", "0", "100");
        dynamic_settings.push_back(setting);
    }

    if(DriverSettings.size())
        MDFN_MergeSettings(DriverSettings);

    // First merge all settable settings, then load the settings from the SETTINGS FILE OF DOOOOM
    MDFN_MergeSettings(MednafenSettings);
    MDFN_MergeSettings(dynamic_settings);
    MDFN_MergeSettings(MDFNMP_Settings);


    for(unsigned int x = 0; x < MDFNSystems.size(); x++)
    {
        if(MDFNSystems[x]->Settings)
            MDFN_MergeSettings(MDFNSystems[x]->Settings);
    }

    MDFN_MergeSettings(RenamedSettings);

    if(!MFDN_LoadSettings(basedir))
        return(0);

#ifdef WANT_DEBUGGER
    MDFNDBG_Init();
#endif

    return(1);
}

void MDFNI_Kill(void)
{
    MDFN_SaveSettings();
}

static double multiplier_save, volume_save;
static std::vector<int16> SoundBufPristine;

static void ProcessAudio(EmulateSpecStruct *espec)
{
    if(espec->SoundVolume != 1)
        volume_save = espec->SoundVolume;

    if(espec->soundmultiplier != 1)
        multiplier_save = espec->soundmultiplier;

    if(espec->SoundBuf && espec->SoundBufSize)
    {
        int16 *const SoundBuf = espec->SoundBuf + espec->SoundBufSizeALMS * MDFNGameInfo->soundchan;
        int32 SoundBufSize = espec->SoundBufSize - espec->SoundBufSizeALMS;
        const int32 SoundBufMaxSize = espec->SoundBufMaxSize - espec->SoundBufSizeALMS;


        if(qtrecorder && (volume_save != 1 || multiplier_save != 1))
        {
            int32 orig_size = SoundBufPristine.size();

            SoundBufPristine.resize(orig_size + SoundBufSize * MDFNGameInfo->soundchan);
            for(int i = 0; i < SoundBufSize * MDFNGameInfo->soundchan; i++)
                SoundBufPristine[orig_size + i] = SoundBuf[i];
        }

        if(espec->NeedSoundReverse)
        {
            int16 *yaybuf = SoundBuf;
            int32 slen = SoundBufSize;

            if(MDFNGameInfo->soundchan == 1)
            {
                for(int x = 0; x < (slen / 2); x++)
                {
                    int16 cha = yaybuf[slen - x - 1];
                    yaybuf[slen - x - 1] = yaybuf[x];
                    yaybuf[x] = cha;
                }
            }
            else if(MDFNGameInfo->soundchan == 2)
            {
                for(int x = 0; x < (slen * 2) / 2; x++)
                {
                    int16 cha = yaybuf[slen * 2 - (x&~1) - ((x&1) ^ 1) - 1];
                    yaybuf[slen * 2 - (x&~1) - ((x&1) ^ 1) - 1] = yaybuf[x];
                    yaybuf[x] = cha;
                }
            }
        }

        try
        {
            if(wavrecorder)
                wavrecorder->WriteSound(SoundBuf, SoundBufSize);
        }
        catch(std::exception &e)
        {
            MDFND_PrintError(e.what());
            delete wavrecorder;
            wavrecorder = NULL;
        }

        if(multiplier_save != LastSoundMultiplier)
        {
            ff_resampler.time_ratio(multiplier_save, 0.9965);
            LastSoundMultiplier = multiplier_save;
        }

        if(multiplier_save != 1)
        {
            if(FFDiscard)
            {
                if(SoundBufSize >= multiplier_save)
                    SoundBufSize /= multiplier_save;
            }
            else
            {
                if(MDFNGameInfo->soundchan == 2)
                {
                    assert(ff_resampler.max_write() >= SoundBufSize * 2);

                    for(int i = 0; i < SoundBufSize * 2; i++)
                        ff_resampler.buffer()[i] = SoundBuf[i];
                }
                else
                {
                    assert(ff_resampler.max_write() >= SoundBufSize * 2);

                    for(int i = 0; i < SoundBufSize; i++)
                    {
                        ff_resampler.buffer()[i * 2] = SoundBuf[i];
                        ff_resampler.buffer()[i * 2 + 1] = 0;
                    }
                }
                ff_resampler.write(SoundBufSize * 2);

                int avail = ff_resampler.avail();
                int real_read = std::min((int)(SoundBufMaxSize * MDFNGameInfo->soundchan), avail);

                if(MDFNGameInfo->soundchan == 2)
                    SoundBufSize = ff_resampler.read(SoundBuf, real_read ) >> 1;
                else
                    SoundBufSize = ff_resampler.read_mono_hack(SoundBuf, real_read );

                avail -= real_read;

                if(avail > 0)
                {
                    printf("ff_resampler.avail() > espec->SoundBufMaxSize * MDFNGameInfo->soundchan - %d\n", avail);
                    ff_resampler.clear();
                }
            }
        }

        if(volume_save != 1)
        {
            if(volume_save < 1)
            {
                int volume = (int)(16384 * volume_save);

                for(int i = 0; i < SoundBufSize * MDFNGameInfo->soundchan; i++)
                    SoundBuf[i] = (SoundBuf[i] * volume) >> 14;
            }
            else
            {
Пример #11
0
MDFNGI *MDFNI_LoadCD(const char *force_module, const char *devicename)
{
    uint8 LayoutMD5[16];

    MDFNI_CloseGame();

    LastSoundMultiplier = 1;

    MDFN_printf(_("Loading %s...\n\n"), devicename ? devicename : _("PHYSICAL CD"));

    try
    {
        if(devicename && strlen(devicename) > 4 && !strcasecmp(devicename + strlen(devicename) - 4, ".m3u"))
        {
            std::vector<std::string> file_list;

            ReadM3U(file_list, devicename);

            for(unsigned i = 0; i < file_list.size(); i++)
            {
                CDInterfaces.push_back(new CDIF(file_list[i].c_str()));
            }

            GetFileBase(devicename);
        }
        else
        {
            CDInterfaces.push_back(new CDIF(devicename));
            if(CDInterfaces[0]->IsPhysical())
            {
                GetFileBase("cdrom");
            }
            else
                GetFileBase(devicename);
        }
    }
    catch(std::exception &e)
    {
        MDFND_PrintError(e.what());
        MDFN_PrintError(_("Error opening CD."));
        return(0);
    }

//
// Print out a track list for all discs.
//
    MDFN_indent(1);
    for(unsigned i = 0; i < CDInterfaces.size(); i++)
    {
        CDUtility::TOC toc;

        CDInterfaces[i]->ReadTOC(&toc);

        MDFN_printf(_("CD %d Layout:\n"), i + 1);
        MDFN_indent(1);

        for(int32 track = toc.first_track; track <= toc.last_track; track++)
        {
            MDFN_printf(_("Track %2d, LBA: %6d  %s\n"), track, toc.tracks[track].lba, (toc.tracks[track].control & 0x4) ? "DATA" : "AUDIO");
        }

        MDFN_printf("Leadout: %6d\n", toc.tracks[100].lba);
        MDFN_indent(-1);
        MDFN_printf("\n");
    }
    MDFN_indent(-1);
//
//



// Calculate layout MD5.  The system emulation LoadCD() code is free to ignore this value and calculate
// its own, or to use it to look up a game in its database.
    {
        md5_context layout_md5;

        layout_md5.starts();

        for(unsigned i = 0; i < CDInterfaces.size(); i++)
        {
            CD_TOC toc;

            CDInterfaces[i]->ReadTOC(&toc);

            layout_md5.update_u32_as_lsb(toc.first_track);
            layout_md5.update_u32_as_lsb(toc.last_track);
            layout_md5.update_u32_as_lsb(toc.tracks[100].lba);

            for(uint32 track = toc.first_track; track <= toc.last_track; track++)
            {
                layout_md5.update_u32_as_lsb(toc.tracks[track].lba);
                layout_md5.update_u32_as_lsb(toc.tracks[track].control & 0x4);
            }
        }

        layout_md5.finish(LayoutMD5);
    }

    MDFNGameInfo = NULL;

    for(std::list<MDFNGI *>::iterator it = MDFNSystemsPrio.begin(); it != MDFNSystemsPrio.end(); it++)  //_unsigned int x = 0; x < MDFNSystems.size(); x++)
    {
        char tmpstr[256];
        trio_snprintf(tmpstr, 256, "%s.enable", (*it)->shortname);

        if(force_module)
        {
            if(!strcmp(force_module, (*it)->shortname))
            {
                MDFNGameInfo = *it;
                break;
            }
        }
        else
        {
            // Is module enabled?
            if(!MDFN_GetSettingB(tmpstr))
                continue;

            if(!(*it)->LoadCD || !(*it)->TestMagicCD)
                continue;

            if((*it)->TestMagicCD(&CDInterfaces))
            {
                MDFNGameInfo = *it;
                break;
            }
        }
    }

    if(!MDFNGameInfo)
    {
        if(force_module)
        {
            MDFN_PrintError(_("Unrecognized system \"%s\"!"), force_module);
            return(0);
        }

        // This code path should never be taken, thanks to "cdplay"
        MDFN_PrintError(_("Could not find a system that supports this CD."));
        return(0);
    }

    // This if statement will be true if force_module references a system without CDROM support.
    if(!MDFNGameInfo->LoadCD)
    {
        MDFN_PrintError(_("Specified system \"%s\" doesn't support CDs!"), force_module);
        return(0);
    }

    MDFN_printf(_("Using module: %s(%s)\n\n"), MDFNGameInfo->shortname, MDFNGameInfo->fullname);


// TODO: include module name in hash
    memcpy(MDFNGameInfo->MD5, LayoutMD5, 16);

    if(!(MDFNGameInfo->LoadCD(&CDInterfaces)))
    {
        for(unsigned i = 0; i < CDInterfaces.size(); i++)
            delete CDInterfaces[i];
        CDInterfaces.clear();

        MDFNGameInfo = NULL;
        return(0);
    }

    MDFNI_SetLayerEnableMask(~0ULL);

#ifdef WANT_DEBUGGER
    MDFNDBG_PostGameLoad();
#endif

    MDFNSS_CheckStates();
    MDFNMOV_CheckMovies();

    MDFN_ResetMessages();   // Save state, status messages, etc.

    TBlur_Init();

    MDFN_StateEvilBegin();


    if(MDFNGameInfo->GameType != GMT_PLAYER)
    {
        MDFN_LoadGameCheats(NULL);
        MDFNMP_InstallReadPatches();
    }

    last_sound_rate = -1;
    memset(&last_pixel_format, 0, sizeof(MDFN_PixelFormat));

    return(MDFNGameInfo);
}
Пример #12
0
static void ProcessAudio(EmulateSpecStruct *espec)
{
 if(espec->SoundVolume != 1)
  volume_save = espec->SoundVolume;

 if(espec->soundmultiplier != 1)
  multiplier_save = espec->soundmultiplier;

 if(espec->SoundBuf && espec->SoundBufSize)
 {
  int16 *const SoundBuf = espec->SoundBuf + espec->SoundBufSizeALMS * MDFNGameInfo->soundchan;
  int32 SoundBufSize = espec->SoundBufSize - espec->SoundBufSizeALMS;
  const int32 SoundBufMaxSize = espec->SoundBufMaxSize - espec->SoundBufSizeALMS;


  if(qtrecorder && (volume_save != 1 || multiplier_save != 1))
  {
   int32 orig_size = SoundBufPristine.size();

   SoundBufPristine.resize(orig_size + SoundBufSize * MDFNGameInfo->soundchan);
   for(int i = 0; i < SoundBufSize * MDFNGameInfo->soundchan; i++)
    SoundBufPristine[orig_size + i] = SoundBuf[i];
  }

#if 0
  //
  // Sine wave sweep for test purposes.
  //
  {
   static double phase = 0;
   static double phase_inc = 0.000;
   static double phase_inc_inc = 0.000003;
   static int32 scounter = 0;

   int16 *sbuf = SoundBuf;
   int32 slen = SoundBufSize;


   if(MDFNGameInfo->soundchan == 2)
   {
    for(int i = 0; i < slen; i++)
    {
     int16 tmp = 127 * 256 * sin(phase);

     tmp = (scounter & 8) ? 127 * 256 : -127 * 256;

     sbuf[i * 2 + 0] = tmp;
     sbuf[i * 2 + 1] = tmp;
     phase += phase_inc;
     phase_inc += phase_inc_inc;
     scounter++;
    }
   }
   else
   {
    for(int i = 0; i < slen; i++)
    {
     int16 tmp = 127 * 256 * sin(phase);

     tmp = (scounter & 8) ? 127 * 256 : -127 * 256;

     sbuf[i] = tmp;

     phase += phase_inc;
     phase_inc += phase_inc_inc;
     scounter++;
    }
   }
  }

#endif

  if(espec->NeedSoundReverse)
  {
   int16 *yaybuf = SoundBuf;
   int32 slen = SoundBufSize;

   if(MDFNGameInfo->soundchan == 1)
   {
    for(int x = 0; x < (slen / 2); x++)    
    {
     int16 cha = yaybuf[slen - x - 1];
     yaybuf[slen - x - 1] = yaybuf[x];
     yaybuf[x] = cha;
    }
   }
   else if(MDFNGameInfo->soundchan == 2)
   {
    for(int x = 0; x < (slen * 2) / 2; x++)
    {
     int16 cha = yaybuf[slen * 2 - (x&~1) - ((x&1) ^ 1) - 1];
     yaybuf[slen * 2 - (x&~1) - ((x&1) ^ 1) - 1] = yaybuf[x];
     yaybuf[x] = cha;
    }
   }
  }

  try
  {
   if(wavrecorder)
    wavrecorder->WriteSound(SoundBuf, SoundBufSize);
  }
  catch(std::exception &e)
  {
   MDFND_PrintError(e.what());
   delete wavrecorder;
   wavrecorder = NULL;
  }

  if(multiplier_save != LastSoundMultiplier)
  {
   ff_resampler.time_ratio(multiplier_save, 0.9965);
   LastSoundMultiplier = multiplier_save;
  }

  if(multiplier_save != 1)
  {
   if(FFDiscard)
   {
    if(SoundBufSize >= multiplier_save)
     SoundBufSize /= multiplier_save;
   }
   else
   {
    if(MDFNGameInfo->soundchan == 2)
    {
     assert(ff_resampler.max_write() >= SoundBufSize * 2);

     for(int i = 0; i < SoundBufSize * 2; i++)
      ff_resampler.buffer()[i] = SoundBuf[i];
    }
    else
    {
     assert(ff_resampler.max_write() >= SoundBufSize * 2);

     for(int i = 0; i < SoundBufSize; i++)
     {
      ff_resampler.buffer()[i * 2] = SoundBuf[i];
      ff_resampler.buffer()[i * 2 + 1] = 0;
     }
    }   
    ff_resampler.write(SoundBufSize * 2);

    int avail = ff_resampler.avail();
    int real_read = std::min((int)(SoundBufMaxSize * MDFNGameInfo->soundchan), avail);

    if(MDFNGameInfo->soundchan == 2)
     SoundBufSize = ff_resampler.read(SoundBuf, real_read ) >> 1;
    else
     SoundBufSize = ff_resampler.read_mono_hack(SoundBuf, real_read );

    avail -= real_read;

    if(avail > 0)
    {
     printf("ff_resampler.avail() > espec->SoundBufMaxSize * MDFNGameInfo->soundchan - %d\n", avail);
     ff_resampler.clear();
    }
   }
  }
Пример #13
0
MDFNGI *MDFNI_LoadCD(const char *force_module, const char *devicename)
{
 uint8 LayoutMD5[16];
#ifdef NEED_CD
 static std::vector<CDIF *> CDInterfaces;	// FIXME: Cleanup on error out.
#endif

 MDFN_printf(_("Loading %s...\n\n"), devicename ? devicename : _("PHYSICAL CD"));

 try
 {
  if(devicename && strlen(devicename) > 4 && !strcasecmp(devicename + strlen(devicename) - 4, ".m3u"))
  {
   std::vector<std::string> file_list;

   ReadM3U(file_list, devicename);

   for(unsigned i = 0; i < file_list.size(); i++)
   {
    CDInterfaces.push_back(CDIF_Open(file_list[i].c_str(), false /* cdimage_memcache */));
   }
  }
  else
  {
   CDInterfaces.push_back(CDIF_Open(devicename, false /* cdimage_memcache */));
  }
 }
 catch(std::exception &e)
 {
  MDFND_PrintError(e.what());
  MDFN_PrintError(_("Error opening CD."));
  return(0);
 }

 //
 // Print out a track list for all discs.
 //
 MDFN_indent(1);
 for(unsigned i = 0; i < CDInterfaces.size(); i++)
 {
  CDUtility::TOC toc;

  CDInterfaces[i]->ReadTOC(&toc);

  MDFN_printf(_("CD %d Layout:\n"), i + 1);
  MDFN_indent(1);

  for(int32 track = toc.first_track; track <= toc.last_track; track++)
  {
   MDFN_printf(_("Track %2d, LBA: %6d  %s\n"), track, toc.tracks[track].lba, (toc.tracks[track].control & 0x4) ? "DATA" : "AUDIO");
  }

  MDFN_printf("Leadout: %6d\n", toc.tracks[100].lba);
  MDFN_indent(-1);
  MDFN_printf("\n");
 }
 MDFN_indent(-1);

 // Calculate layout MD5.  The system emulation LoadCD() code is free to ignore this value and calculate
 // its own, or to use it to look up a game in its database.
 {
  md5_context layout_md5;

  layout_md5.starts();

  for(unsigned i = 0; i < CDInterfaces.size(); i++)
  {
   CD_TOC toc;

   CDInterfaces[i]->ReadTOC(&toc);

   layout_md5.update_u32_as_lsb(toc.first_track);
   layout_md5.update_u32_as_lsb(toc.last_track);
   layout_md5.update_u32_as_lsb(toc.tracks[100].lba);

   for(uint32 track = toc.first_track; track <= toc.last_track; track++)
   {
    layout_md5.update_u32_as_lsb(toc.tracks[track].lba);
    layout_md5.update_u32_as_lsb(toc.tracks[track].control & 0x4);
   }
  }

  layout_md5.finish(LayoutMD5);
 }

 // This if statement will be true if force_module references a system without CDROM support.
 if(!MDFNGameInfo->LoadCD)
 {
    MDFN_PrintError(_("Specified system \"%s\" doesn't support CDs!"), force_module);
    return(0);
 }

 MDFN_printf(_("Using module: %s(%s)\n\n"), MDFNGameInfo->shortname, MDFNGameInfo->fullname);

 // TODO: include module name in hash
 memcpy(MDFNGameInfo->MD5, LayoutMD5, 16);

 if(!(MDFNGameInfo->LoadCD(&CDInterfaces)))
 {
  for(unsigned i = 0; i < CDInterfaces.size(); i++)
   delete CDInterfaces[i];
  CDInterfaces.clear();

  MDFNGameInfo = NULL;
  return(0);
 }

 //MDFNI_SetLayerEnableMask(~0ULL);

 #ifdef WANT_DEBUGGER
 MDFNDBG_PostGameLoad(); 
 #endif

 MDFN_ResetMessages();   // Save state, status messages, etc.

// MDFN_LoadGameCheats(NULL);
 MDFNMP_InstallReadPatches();

 return(MDFNGameInfo);
}
Пример #14
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);
}
Пример #15
0
void PumpWrap(void)
{
 SDL_Event event;
 SDL_Event gtevents_temp[gtevents_size];
 int numevents = 0;

 bool NITI;

 NITI = Netplay_IsTextInput();

 if(Debugger_IsActive() || NITI || IsConsoleCheatConfigActive() || Help_IsActive())
 {
  if(!krepeat)
   SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
  krepeat = 1;
 }
 else
 {
  if(krepeat)
   SDL_EnableKeyRepeat(0, 0);
  krepeat = 0;
 }

 while(SDL_PollEvent(&event))
 {
  if(Debugger_IsActive())
   Debugger_Event(&event);
  else 
   if(IsConsoleCheatConfigActive())
    CheatEventHook(&event);

  NetplayEventHook(&event);

  /* This is a very ugly hack for some joystick hats that don't behave very well. */
  if(event.type == SDL_JOYHATMOTION)
  {
   SDL_Event ne[64];
   int count;
   //printf("Cheep: %d\n", event.jhat.value);
   if((count = SDL_PeepEvents(ne, 64, SDL_PEEKEVENT, SDL_EVENTMASK(SDL_JOYHATMOTION))) >= 1)
   {
    int x;
    int docon = 0;

    for(x=0;x<count;x++)
     if(event.jhat.which == ne[x].jhat.which)
      docon = 1;
    if(docon) continue;
   }
  } // && event.jhat.
  //if(event.type == SDL_JOYAXISMOTION) printf("Which: %d, axis: %d, value: %d\n", event.jaxis.which, event.jaxis.axis, event.jaxis.value);

  /* Handle the event, and THEN hand it over to the GUI. Order is important due to global variable mayhem(CEVT_TOGGLEFS. */
  switch(event.type)
  {
   case SDL_ACTIVEEVENT: break;
   case SDL_SYSWMEVENT: break;
   case SDL_VIDEORESIZE: VideoResize(event.resize.w, event.resize.h); break;
   case SDL_VIDEOEXPOSE: break;
   case SDL_QUIT: NeedExitNow = 1;break;
   case SDL_USEREVENT:
		switch(event.user.code)
		{
		 case CEVT_SET_STATE_STATUS: MT_SetStateStatus((StateStatusStruct *)event.user.data1); break;
                 case CEVT_SET_MOVIE_STATUS: MT_SetMovieStatus((StateStatusStruct *)event.user.data1); break;
		 case CEVT_WANT_EXIT:
		     if(!Netplay_TryTextExit())
		     {
		      SDL_Event evt;
		      evt.quit.type = SDL_QUIT;
		      SDL_PushEvent(&evt);
		     }
		     break;
	         case CEVT_SET_GRAB_INPUT:
                         SDL_WM_GrabInput(*(int *)event.user.data1 ? SDL_GRAB_ON : SDL_GRAB_OFF);
                         free(event.user.data1);
                         break;
		 case CEVT_TOGGLEFS: NeedVideoChange = 1; break;
		 case CEVT_VIDEOSYNC: NeedVideoChange = -1; break;
		 case CEVT_PRINTERROR: MDFND_PrintError((char *)event.user.data1); free(event.user.data1); break;
		 case CEVT_PRINTMESSAGE: MDFND_Message((char *)event.user.data1); free(event.user.data1); break;
		 case CEVT_SHOWCURSOR: SDL_ShowCursor(*(int *)event.user.data1); free(event.user.data1); break;
	  	 case CEVT_DISP_MESSAGE: VideoShowMessage((UTF8*)event.user.data1); break;
		 default: 
			if(numevents < gtevents_size)
			{
			 memcpy(&gtevents_temp[numevents], &event, sizeof(SDL_Event));
			 numevents++;
			}
			break;
		}
		break;
   default: 
           if(numevents < gtevents_size)
           {
            memcpy(&gtevents_temp[numevents], &event, sizeof(SDL_Event));
            numevents++;
           }
	   break;
  }
 }

 SDL_mutexP(EVMutex);
 for(int i = 0; i < numevents; i++)
 {
  memcpy((void *)&gtevents[gte_write], &gtevents_temp[i], sizeof(SDL_Event));
  gte_write = (gte_write + 1) & (gtevents_size - 1);
 }
 SDL_mutexV(EVMutex);

 if(!CurGame)
  GameThread_HandleEvents();
}