Пример #1
0
static void LoadCPalette(const char *syspalname, uint8 **ptr, uint32 num_entries)
{
 std::string colormap_fn = MDFN_MakeFName(MDFNMKF_PALETTE, 0, syspalname).c_str();

 MDFN_printf(_("Loading custom palette from \"%s\"...\n"),  colormap_fn.c_str());
 MDFN_indent(1);

 try
 {
  FileStream fp(colormap_fn.c_str(), FileStream::MODE_READ);

  *ptr = new uint8[num_entries * 3];

  fp.read(*ptr, num_entries * 3);
 }
 catch(MDFN_Error &e)
 {
  MDFN_printf(_("Error: %s\n"), e.what());
  MDFN_indent(-1);

  if(e.GetErrno() != ENOENT)
   throw;

  return;
 }
 catch(std::exception &e)
 {
  MDFN_printf(_("Error: %s\n"), e.what());
  MDFN_indent(-1);
  throw;
 }

 MDFN_indent(-1);
}
Пример #2
0
static bool cdif_open_sub(const char *device_name)
{
 MDFN_printf(_("Loading %s...\n\n"), device_name ? device_name : _("PHYSICAL CDROM DISC"));
 MDFN_indent(1);

 if(!(p_cdrfile = cdrfile_open(device_name)))
 {
  MDFN_indent(-1);
  return(0);
 }

 CD_Info.NumTracks = cdrfile_get_num_tracks(p_cdrfile);
 if(CD_Info.NumTracks < 1 || CD_Info.NumTracks > 100)
 {
  MDFN_indent(-1);
  return(0);
 }

 CD_Info.FirstTrack = cdrfile_get_first_track_num(p_cdrfile);

 for(track_t track = CD_Info.FirstTrack; track < CD_Info.FirstTrack + CD_Info.NumTracks; track++)
 {
  CD_Info.Tracks[track].LSN = cdrfile_get_track_lsn(p_cdrfile, track);
  CD_Info.Tracks[track].Format = cdrfile_get_track_format(p_cdrfile, track);
  MDFN_printf(_("Track %2d, LSN: %6d %s\n"), track, CD_Info.Tracks[track].LSN, track_format2str[CD_Info.Tracks[track].Format]);
 }
 MDFN_indent(-1);
 return(1);
}
Пример #3
0
// Return FALSE on fatal error(IPS file found but couldn't be applied),
// or TRUE on success(IPS patching succeeded, or IPS file not found).
static bool LoadIPS(MDFNFILE &GameFile, const char *path)
{
 FILE *IPSFile;

 MDFN_printf(_("Applying IPS file \"%s\"...\n"), path);

 IPSFile = fopen(path, "rb");
 if(!IPSFile)
 {
  ErrnoHolder ene(errno);

  MDFN_indent(1);
  MDFN_printf(_("Failed: %s\n"), ene.StrError());
  MDFN_indent(-1);

  if(ene.Errno() == ENOENT)
   return(1);
  else
  {
   MDFN_PrintError(_("Error opening IPS file: %s\n"), ene.StrError());
   return(0);
  }  
 }

 if(!GameFile.ApplyIPS(IPSFile))
 {
  fclose(IPSFile);
  return(0);
 }
 fclose(IPSFile);

 return(1);
}
Пример #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
static bool LoadCPalette(const char *syspalname, uint8 **ptr, uint32 num_entries)
{
 std::string colormap_fn = MDFN_MakeFName(MDFNMKF_PALETTE, 0, syspalname).c_str();

 MDFN_printf(_("Loading custom palette from \"%s\"...\n"),  colormap_fn.c_str());
 MDFN_indent(1);

 *ptr = NULL;
 try
 {
  FileStream fp(colormap_fn.c_str(), FileStream::MODE_READ);

  if(!(*ptr = (uint8 *)MDFN_malloc(num_entries * 3, _("custom color map"))))
  {
   MDFN_indent(-1);
   return(false);
  }

  fp.read(*ptr, num_entries * 3);
 }
 catch(MDFN_Error &e)
 {
  if(*ptr)
  {
   MDFN_free(*ptr);
   *ptr = NULL;
  }

  MDFN_printf(_("Error: %s\n"), e.what());
  MDFN_indent(-1);
  return(e.GetErrno() == ENOENT);        // Return fatal error if it's an error other than the file not being found.
 }
 catch(std::exception &e)
 {
  if(*ptr)
  {
   MDFN_free(*ptr);
   *ptr = NULL;
  }

  MDFN_printf(_("Error: %s\n"), e.what());
  MDFN_indent(-1);
  return(false);
 }

 MDFN_indent(-1);

 return(true);
}
Пример #6
0
static void LoadCommonPost(const md_game_info &ginfo)
{
 MDFN_printf(_("ROM:       %dKiB\n"), (ginfo.rom_size + 1023) / 1024);
 MDFN_printf(_("ROM CRC32: 0x%08x\n"), ginfo.crc32);
 MDFN_printf(_("ROM MD5:   0x%s\n"), md5_context::asciistr(ginfo.md5, 0).c_str());
 MDFN_printf(_("Header MD5: 0x%s\n"), md5_context::asciistr(ginfo.info_header_md5, 0).c_str());
 MDFN_printf(_("Product Code: %s\n"), ginfo.product_code);
 MDFN_printf(_("Domestic name: %s\n"), ginfo.domestic_name); // TODO: Character set conversion(shift_jis -> utf-8)
 MDFN_printf(_("Overseas name: %s\n"), ginfo.overseas_name);
 MDFN_printf(_("Copyright: %s\n"), ginfo.copyright);
 if(ginfo.checksum == ginfo.checksum_real)
  MDFN_printf(_("Checksum:  0x%04x\n"), ginfo.checksum);
 else
  MDFN_printf(_("Checksum:  0x%04x\n Warning: calculated checksum(0x%04x) does not match\n"), ginfo.checksum, ginfo.checksum_real);

 MDFN_printf(_("Supported I/O devices:\n"));
 MDFN_indent(1);
 for(unsigned int iot = 0; iot < sizeof(IO_types) / sizeof(IO_type_t); iot++)
 {
  if(ginfo.io_support & (1 << IO_types[iot].id))
   MDFN_printf(_("%s\n"), _(IO_types[iot].name));
 }
 MDFN_indent(-1);

 MDFNMP_Init(8192, (1 << 24) / 8192);
 MDFNMP_AddRAM(65536, 0x7 << 21, work_ram);

 MDFNGameInfo->GameSetMD5Valid = FALSE;

 MDSound_Init();

 MDFN_printf(_("Supported regions:\n"));
 MDFN_indent(1);
 if(ginfo.region_support & REGIONMASK_JAPAN_NTSC)
  MDFN_printf(_("Japan/Domestic NTSC\n"));
 if(ginfo.region_support & REGIONMASK_JAPAN_PAL)
  MDFN_printf(_("Japan/Domestic PAL\n"));
 if(ginfo.region_support & REGIONMASK_OVERSEAS_NTSC)
  MDFN_printf(_("Overseas NTSC\n"));
 if(ginfo.region_support & REGIONMASK_OVERSEAS_PAL)
  MDFN_printf(_("Overseas PAL\n"));
 MDFN_indent(-1);

 {
  const int region_setting = MDFN_GetSettingI("md.region");
  const int reported_region_setting = MDFN_GetSettingI("md.reported_region");

  // Default, in case the game doesn't support any regions!
  bool game_overseas = TRUE;
  bool game_pal = FALSE;
  bool overseas;
  bool pal;
  bool overseas_reported;
  bool pal_reported;

  // Preference order, TODO:  Make it configurable
  if(ginfo.region_support & REGIONMASK_OVERSEAS_NTSC)
  {
   game_overseas = TRUE;
   game_pal = FALSE;
  }
  else if(ginfo.region_support & REGIONMASK_JAPAN_NTSC)
  {
   game_overseas = FALSE;
   game_pal = FALSE;
  }
  else if(ginfo.region_support & REGIONMASK_OVERSEAS_PAL)
  {
   game_overseas = TRUE;
   game_pal = TRUE;
  }
  else if(ginfo.region_support & REGIONMASK_JAPAN_PAL) // WTF?
  {
   game_overseas = FALSE;
   game_pal = TRUE;
  }
 
  if(region_setting == REGION_GAME)
  {
   overseas = game_overseas;
   pal = game_pal;
  }
  else
  {
   decode_region_setting(region_setting, overseas, pal);
  }

  if(reported_region_setting == REGION_GAME)
  {
   overseas_reported = game_overseas;
   pal_reported = game_pal;
  }
  else if(reported_region_setting == REGION_SAME)
  {
   overseas_reported = overseas;
   pal_reported = pal;   
  }
  else
  {
   decode_region_setting(reported_region_setting, overseas_reported, pal_reported);
  }

  MDFN_printf("\n");
  MDFN_printf(_("Active Region: %s %s\n"), overseas ? _("Overseas") : _("Domestic"), pal ? _("PAL") : _("NTSC"));
  MDFN_printf(_("Active Region Reported: %s %s\n"), overseas_reported ? _("Overseas") : _("Domestic"), pal_reported ? _("PAL") : _("NTSC"));

  system_init(overseas, pal, overseas_reported, pal_reported);

  if(pal)
   MDFNGameInfo->nominal_height = 240;
  else
   MDFNGameInfo->nominal_height = 224;

  MDFNGameInfo->MasterClock = MDFN_MASTERCLOCK_FIXED(pal ? CLOCK_PAL : CLOCK_NTSC);

  if(pal)
   MDFNGameInfo->fps = (int64)CLOCK_PAL * 65536 * 256 / (313 * 3420);
  else
   MDFNGameInfo->fps = (int64)CLOCK_NTSC * 65536 * 256 / (262 * 3420);

  //printf("%f\n", (double)MDFNGameInfo->fps / 65536 / 256);
 }

 if(MDFN_GetSettingB("md.correct_aspect"))
 {
  MDFNGameInfo->nominal_width = 292;
  MDFNGameInfo->lcm_width = 1280;
 }
 else
 {
  MDFNGameInfo->nominal_width = 320;
  MDFNGameInfo->lcm_width = 320;
 }

 MDFNGameInfo->lcm_height = MDFNGameInfo->nominal_height * 2;

 MDFNGameInfo->LayerNames = "BG0\0BG1\0OBJ\0";

 //
 //
 {
  unsigned mtt = MDFN_GetSettingUI("md.input.multitap");

  if(MDFN_GetSettingB("md.input.auto"))
  {
   for(auto const& e : InputDB)
   {
    if(e.crc32 == ginfo.crc32 && (!e.prod_code || !strcmp(e.prod_code, ginfo.product_code)))
    {
     MDFNGameInfo->DesiredInput.resize(8);

     for(unsigned n = e.max_players; n < 8; n++)	// Particularly for Gauntlet 4.
      MDFNGameInfo->DesiredInput[n] = "none";

     mtt = e.tap;
     break;
    }
   }
  }

  for(const auto* mte = MultiTap_List; mte->string; mte++)
  {
   if((unsigned)mte->number == mtt)
   {
    MDFN_printf(_("Active Multitap(s): %s\n"), mte->description);
    break;
   }
  }

  MDINPUT_SetMultitap(mtt);
 }

 //
 //

 system_reset(true);
}
Пример #7
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);
}
Пример #8
0
MDFNGI *MDFNI_LoadGame(const char *force_module, const char *name)
{
    MDFNFILE GameFile;
    struct stat stat_buf;
    std::vector<FileExtensionSpecStruct> valid_iae;

    if(strlen(name) > 4 && (!strcasecmp(name + strlen(name) - 4, ".cue") || !strcasecmp(name + strlen(name) - 4, ".toc") || !strcasecmp(name + strlen(name) - 4, ".m3u")))
    {
        return(MDFNI_LoadCD(force_module, name));
    }

    if(!stat(name, &stat_buf) && !S_ISREG(stat_buf.st_mode))
    {
        return(MDFNI_LoadCD(force_module, name));
    }

    MDFNI_CloseGame();

    LastSoundMultiplier = 1;

    MDFNGameInfo = NULL;

    MDFN_printf(_("Loading %s...\n"),name);

    MDFN_indent(1);

    GetFileBase(name);

    // Construct a NULL-delimited list of known file extensions for MDFN_fopen()
    for(unsigned int i = 0; i < MDFNSystems.size(); i++)
    {
        const FileExtensionSpecStruct *curexts = MDFNSystems[i]->FileExtensions;

        // If we're forcing a module, only look for extensions corresponding to that module
        if(force_module && strcmp(MDFNSystems[i]->shortname, force_module))
            continue;

        if(curexts)
            while(curexts->extension && curexts->description)
            {
                valid_iae.push_back(*curexts);
                curexts++;
            }
    }
    {
        FileExtensionSpecStruct tmpext = { NULL, NULL };
        valid_iae.push_back(tmpext);
    }

    if(!GameFile.Open(name, &valid_iae[0], _("game")))
    {
        MDFNGameInfo = NULL;
        return 0;
    }

    if(!LoadIPS(GameFile, MDFN_MakeFName(MDFNMKF_IPS, 0, 0).c_str()))
    {
        MDFNGameInfo = NULL;
        GameFile.Close();
        return(0);
    }

    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))
            {
                if(!(*it)->Load)
                {
                    GameFile.Close();

                    if((*it)->LoadCD)
                        MDFN_PrintError(_("Specified system only supports CD(physical, or image files, such as *.cue and *.toc) loading."));
                    else
                        MDFN_PrintError(_("Specified system does not support normal file loading."));
                    MDFN_indent(-1);
                    MDFNGameInfo = NULL;
                    return 0;
                }
                MDFNGameInfo = *it;
                break;
            }
        }
        else
        {
            // Is module enabled?
            if(!MDFN_GetSettingB(tmpstr))
                continue;

            if(!(*it)->Load || !(*it)->TestMagic)
                continue;

            if((*it)->TestMagic(name, &GameFile))
            {
                MDFNGameInfo = *it;
                break;
            }
        }
    }

    if(!MDFNGameInfo)
    {
        GameFile.Close();

        if(force_module)
            MDFN_PrintError(_("Unrecognized system \"%s\"!"), force_module);
        else
            MDFN_PrintError(_("Unrecognized file format.  Sorry."));

        MDFN_indent(-1);
        MDFNGameInfo = NULL;
        return 0;
    }

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

    assert(MDFNGameInfo->soundchan != 0);

    MDFNGameInfo->soundrate = 0;
    MDFNGameInfo->name = NULL;
    MDFNGameInfo->rotated = 0;

    if(MDFNGameInfo->Load(name, &GameFile) <= 0)
    {
        GameFile.Close();
        MDFN_indent(-2);
        MDFNGameInfo = NULL;
        return(0);
    }

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

    MDFNI_SetLayerEnableMask(~0ULL);

#ifdef WANT_DEBUGGER
    MDFNDBG_PostGameLoad();
#endif

    MDFNSS_CheckStates();
    MDFNMOV_CheckMovies();

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

    MDFN_indent(-2);

    if(!MDFNGameInfo->name)
    {
        unsigned int x;
        char *tmp;

        MDFNGameInfo->name = (UTF8 *)strdup(GetFNComponent(name));

        for(x=0; x<strlen((char *)MDFNGameInfo->name); x++)
        {
            if(MDFNGameInfo->name[x] == '_')
                MDFNGameInfo->name[x] = ' ';
        }
        if((tmp = strrchr((char *)MDFNGameInfo->name, '.')))
            *tmp = 0;
    }

    PrevInterlaced = false;
    deint.ClearState();

    TBlur_Init();

    MDFN_StateEvilBegin();


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

    return(MDFNGameInfo);
}
Пример #9
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);
}
Пример #10
0
static int ReadThreadStart(void *arg)
{
 char *device_name = (char *)arg;
 bool Running = TRUE;

 MDFN_printf(_("Loading %s...\n\n"), device_name ? device_name : _("PHYSICAL CDROM DISC"));
 MDFN_indent(1);

 if(!(p_cdrfile = cdrfile_open(device_name)))
 {
  MDFN_indent(-1);
  EmuThreadQueue->Write(CDIF_Message(CDIF_MSG_INIT_DONE, FALSE, 0, 0, 0, NULL));
  return(0);
 }

 if(!cdrfile_read_toc(p_cdrfile, &toc))
 {
  puts("Error reading TOC");
  MDFN_indent(-1);
  EmuThreadQueue->Write(CDIF_Message(CDIF_MSG_INIT_DONE, FALSE, 0, 0, 0, NULL));
  return(0);
 }

 if(toc.first_track < 1 || toc.last_track > 99 || toc.first_track > toc.last_track)
 {
  puts("First/Last track numbers bad");
  MDFN_indent(-1);
  EmuThreadQueue->Write(CDIF_Message(CDIF_MSG_INIT_DONE, FALSE, 0, 0, 0, NULL));
  return(0);
 }

 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);

 EmuThreadQueue->Write(CDIF_Message(CDIF_MSG_INIT_DONE, TRUE, 0, 0, 0, NULL));

 while(Running)
 {
  CDIF_Message msg;

  // Only do a blocking-wait for a message if we don't have any sectors to read-ahead.
  // MDFN_DispMessage("%d %d %d\n", last_read_lba, ra_lba, ra_count);
  if(ReadThreadQueue->Read(&msg, ra_count ? FALSE : TRUE))
  {
   switch(msg.message)
   {
    case CDIF_MSG_DIEDIEDIE: Running = FALSE;
 		 	 break;

    case CDIF_MSG_READ_SECTOR:
			 {
                          static const int max_ra = 16;
			  static const int initial_ra = 1;
			  static const int speedmult_ra = 2;
			  uint32 new_lba = msg.args[0];

			  assert((unsigned int)max_ra < (SBSize / 4));

			  if(new_lba == (last_read_lba + 1))
			  {
			   int how_far_ahead = ra_lba - new_lba;

			   assert(how_far_ahead >= 0);

			   if(how_far_ahead <= max_ra)
			    ra_count = std::min(speedmult_ra, 1 + max_ra - how_far_ahead);
			   else
			    ra_count++;
			  }
			  else
			  {
                           ra_lba = new_lba;
			   ra_count = initial_ra;
			  }
			  last_read_lba = new_lba;
			 }
			 break;
   }
  }

  // Don't read >= the "end" of the disc, silly snake.  Slither.
  if(ra_count && ra_lba == toc.tracks[100].lba)
  {
   ra_count = 0;
   //printf("Ephemeral scarabs: %d!\n", ra_lba);
  }

  if(ra_count)
  {
   uint8 tmpbuf[2352 + 96];

   if(!cdrfile_read_raw_sector(p_cdrfile, tmpbuf, ra_lba))
   {
    printf("Sector %d read error!  Abandon ship!", ra_lba);
    memset(tmpbuf, 0, sizeof(tmpbuf));
   }
   MDFND_LockMutex(SBMutex);

   SectorBuffers[SBWritePos].lba = ra_lba;
   memcpy(SectorBuffers[SBWritePos].data, tmpbuf, 2352 + 96);
   SectorBuffers[SBWritePos].valid = TRUE;
   SBWritePos = (SBWritePos + 1) % SBSize;

   MDFND_UnlockMutex(SBMutex);

   ra_lba++;
   ra_count--;
  }
 }

 if(p_cdrfile)
 {
  cdrfile_destroy(p_cdrfile);
  p_cdrfile = NULL;
 }

 return(1);
}
Пример #11
0
MDFNGI *MDFNI_LoadGame(const char *force_module, const char *name)
{
   MDFNFILE GameFile;
	std::vector<FileExtensionSpecStruct> valid_iae;
   MDFNGameInfo = MDFNGI_CORE;

	MDFN_printf(_("Loading %s...\n"),name);

	MDFN_indent(1);

	// Construct a NULL-delimited list of known file extensions for MDFN_fopen()
   const FileExtensionSpecStruct *curexts = MDFNGameInfo->FileExtensions;

   while(curexts->extension && curexts->description)
   {
      valid_iae.push_back(*curexts);
      curexts++;
   }

	if(!GameFile.Open(name, &valid_iae[0], _("game")))
   {
      MDFNGameInfo = NULL;
      return 0;
   }

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

	//
	// Load per-game settings
	//
	// Maybe we should make a "pgcfg" subdir, and automatically load all files in it?
	// End load per-game settings
	//

   if(MDFNGameInfo->Load(name, &GameFile) <= 0)
   {
      GameFile.Close();
      MDFN_indent(-2);
      MDFNGameInfo = NULL;
      return(0);
   }

	MDFN_LoadGameCheats(NULL);
	MDFNMP_InstallReadPatches();

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

	MDFN_indent(-2);

	if(!MDFNGameInfo->name)
   {
      unsigned int x;
      char *tmp;

      MDFNGameInfo->name = (UTF8 *)strdup(GetFNComponent(name));

      for(x=0;x<strlen((char *)MDFNGameInfo->name);x++)
      {
         if(MDFNGameInfo->name[x] == '_')
            MDFNGameInfo->name[x] = ' ';
      }
      if((tmp = strrchr((char *)MDFNGameInfo->name, '.')))
         *tmp = 0;
   }

   return(MDFNGameInfo);
}
Пример #12
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);
}
Пример #13
0
void NSFLoad(Stream *fp, NESGameType *gt)
{
 try
 {
  char magic[5];
  int x;

  NSFInfo = new NSFINFO();

  fp->rewind();
  fp->read(magic, 5);

  if(!memcmp(magic, "NESM\x1a", 5))
  {
   fp->rewind();
   LoadNSF(fp);
  }
  else if(!memcmp(magic, "NSFE", 4))
  {
   fp->rewind();
   LoadNSFE(NSFInfo, fp, 0);
  }

  if(NSFInfo->LoadAddr < 0x6000)
   throw MDFN_Error(0, _("Load address is invalid!"));

  if(NSFInfo->TotalSongs < 1)
   throw MDFN_Error(0, _("Total number of songs is less than 1!"));

  BSon = 0;
  for(x=0;x<8;x++)
   BSon |= NSFInfo->BankSwitch[x];

  MDFNGameInfo->GameType = GMT_PLAYER;

  if(NSFInfo->GameName.size())
   MDFNGameInfo->name = NSFInfo->GameName;

  for(x=0;;x++)
  {
   if(NSFROM[x]==0x20)
   {
    NSFROM[x+1]=NSFInfo->InitAddr&0xFF;
    NSFROM[x+2]=NSFInfo->InitAddr>>8;
    NSFROM[x+8]=NSFInfo->PlayAddr&0xFF;
    NSFROM[x+9]=NSFInfo->PlayAddr>>8;
    break;
   }
  }

  if(NSFInfo->VideoSystem == 0)
   MDFNGameInfo->VideoSystem = VIDSYS_NTSC;
  else if(NSFInfo->VideoSystem == 1)
   MDFNGameInfo->VideoSystem = VIDSYS_PAL;

  MDFN_printf(_("NSF Loaded.  File information:\n\n"));
  MDFN_indent(1);
  if(NSFInfo->GameName.size())
   MDFN_printf(_("Game/Album Name:\t%s\n"), NSFInfo->GameName.c_str());
  if(NSFInfo->Artist.size())
   MDFN_printf(_("Music Artist:\t%s\n"), NSFInfo->Artist.c_str());
  if(NSFInfo->Copyright.size())
   MDFN_printf(_("Copyright:\t\t%s\n"), NSFInfo->Copyright.c_str());
  if(NSFInfo->Ripper.size())
   MDFN_printf(_("Ripper:\t\t%s\n"), NSFInfo->Ripper.c_str());

  if(NSFInfo->SoundChip)
  {
   static const char *tab[6]={"Konami VRCVI","Konami VRCVII","Nintendo FDS","Nintendo MMC5","Namco 106","Sunsoft FME-07"};

   for(x=0;x<6;x++)
    if(NSFInfo->SoundChip&(1<<x))
    {
     MDFN_printf(_("Expansion hardware:  %s\n"), tab[x]);
     //NSFInfo->SoundChip=1<<x;	/* Prevent confusing weirdness if more than one bit is set. */
     //break;
    }
  }

  if(BSon)
   MDFN_printf(_("Bank-switched\n"));
  MDFN_printf(_("Load address:  $%04x\nInit address:  $%04x\nPlay address:  $%04x\n"),NSFInfo->LoadAddr,NSFInfo->InitAddr,NSFInfo->PlayAddr);
  MDFN_printf("%s\n",(NSFInfo->VideoSystem&1)?"PAL":"NTSC");
  MDFN_printf(_("Starting song:  %d / %d\n\n"),NSFInfo->StartingSong + 1,NSFInfo->TotalSongs);

  if(NSFInfo->SoundChip&4)
   ExWRAM = new uint8[32768+8192];
  else
   ExWRAM = new uint8[8192];

  MDFN_indent(-1);

  gt->Power = NSF_Power;
  gt->Reset = NSF_Reset;
  gt->SaveNV = NULL;
  gt->Kill = NSF_Kill;
  gt->StateAction = NSF_StateAction;

  Player_Init(NSFInfo->TotalSongs, NSFInfo->GameName, NSFInfo->Artist, NSFInfo->Copyright, NSFInfo->SongNames);

  MDFNGameInfo->DesiredInput.push_back("gamepad");
  MDFNGameInfo->DesiredInput.push_back("none");
  MDFNGameInfo->DesiredInput.push_back("none");
  MDFNGameInfo->DesiredInput.push_back("none");
  MDFNGameInfo->DesiredInput.push_back("none");
 }
Пример #14
0
CDRFile *cdrfile_open(const char *path)
{
 CDRFile *ret = (CDRFile *)calloc(1, sizeof(CDRFile));
 struct stat stat_buf;

 if(path == NULL || stat(path, &stat_buf) || !S_ISREG(stat_buf.st_mode))
 {
  CdIo *p_cdio;
  char **devices;
  char **parseit;
  cdio_init();

  GetFileBase("cdrom");

  devices = cdio_get_devices(DRIVER_DEVICE);
  parseit = devices;
  if(parseit)
  {
   MDFN_printf(_("Connected physical devices:\n"));
   MDFN_indent(1);
   while(*parseit)
   {
    MDFN_printf("%s\n", *parseit);
    parseit++;
   }
   MDFN_indent(-1);
  }
  if(!parseit || parseit == devices)
  {
   MDFN_PrintError(_("No CDROM drives detected(or no disc present)."));
   if(devices)
    cdio_free_device_list(devices);
   free(ret);
   return(NULL);
  }

  if(devices)
   cdio_free_device_list(devices);

  p_cdio = cdio_open_cd(path); //, DRIVER_UNKNOWN); //NULL, DRIVER_UNKNOWN);

  if(!p_cdio) 
  {
   free(ret);
   return(NULL);
  }
  ret->p_cdio = p_cdio;

  ret->FirstTrack = cdio_get_first_track_num(ret->p_cdio);
  ret->NumTracks = cdio_get_num_tracks(ret->p_cdio);
  ret->total_sectors = cdio_stat_size(ret->p_cdio);

  if(ret->FirstTrack > 99)
  {
   MDFN_PrintError(_("Invalid first track: %d\n"), ret->FirstTrack);
   free(ret);
   cdio_destroy(p_cdio);
   return(NULL);
  }

  if(ret->NumTracks > 100)
  {
   MDFN_PrintError(_("Invalid track count: %d\n"), ret->NumTracks);
   free(ret);
   cdio_destroy(p_cdio);
   return(NULL);
  }

  for(track_t track = ret->FirstTrack; track < (ret->FirstTrack + ret->NumTracks); track++)
  {
   memset(&ret->Tracks[track], 0, sizeof(CDRFILE_TRACK_INFO));

   ret->Tracks[track].sectors = cdio_get_track_sec_count(ret->p_cdio, track);
   ret->Tracks[track].LSN = cdio_get_track_lsn(ret->p_cdio, track);
   ret->Tracks[track].Format = cdio_get_track_format(ret->p_cdio, track);
  }

  return(ret);
 }

  FILE *fp = fopen(path, "rb");
  bool IsTOC = FALSE;

  // Assign opposite maximum values so our tests will work!
  int FirstTrack = 99;
  int LastTrack = 0;

  if(!fp)
  {
   MDFN_PrintError(_("Error opening CUE sheet/TOC \"%s\": %m\n"), path, errno);
   free(ret);
   return(NULL);
  }
  GetFileBase(path);

  char linebuf[512];
  int32 active_track = -1;
  int32 AutoTrackInc = 1; // For TOC
  CDRFILE_TRACK_INFO TmpTrack;
  memset(&TmpTrack, 0, sizeof(TmpTrack));

  while(fgets(linebuf, 512, fp) > 0)
  {
   char cmdbuf[512], raw_args[512], args[4][512];
   int argcount = 0;

   raw_args[0] = 0;
   cmdbuf[0] = 0;

   args[0][0] = args[1][0] = args[2][0] = args[3][0] = 0;

   if(!strncasecmp(linebuf, "CD_ROM", 6) || !strncasecmp(linebuf, "CD_DA", 5) || !strncasecmp(linebuf, "CD_ROM_XA", 9))
   {
    IsTOC = TRUE;
    puts("TOC file detected.");
   }

   if(IsTOC)
   {
    char *ss_loc = strstr(linebuf, "//");
    if(ss_loc)
    {
     ss_loc[0] = '\n'; // For consistency!
     ss_loc[1] = 0;
    }
   }

   trio_sscanf(linebuf, "%s %[^\r\n]", cmdbuf, raw_args);
   
   if(!strcasecmp(cmdbuf, "CD_ROM") || !strcasecmp(cmdbuf, "CD_DA"))
    IsTOC = TRUE;

   UnQuotify(UnQuotify(UnQuotify(UnQuotify(raw_args, args[0]), args[1]), args[2]), args[3]);
   if(args[0][0])
   {
    argcount++;
    if(args[1][0])
    {
     argcount++;
     if(args[2][0])
     {
      argcount++;
      if(args[3][0])
      {
       argcount++;
      }
     }
    } 
   }

   if(IsTOC)
   {
    if(!strcasecmp(cmdbuf, "TRACK"))
    {
     if(active_track >= 0)
     {
      memcpy(&ret->Tracks[active_track], &TmpTrack, sizeof(TmpTrack));
      memset(&TmpTrack, 0, sizeof(TmpTrack));
      active_track = -1;
     }
 
     if(AutoTrackInc > 99)
     {
      MDFN_printf(_("Invalid track number: %d\n"), AutoTrackInc);
      free(ret);
      return(NULL);
     }

     active_track = AutoTrackInc++;
     if(active_track < FirstTrack)
      FirstTrack = active_track;
     if(active_track > LastTrack)
      LastTrack = active_track;

     if(!strcasecmp(args[0], "AUDIO"))
     {
      TmpTrack.Format = TRACK_FORMAT_AUDIO;
      TmpTrack.RawAudioMSBFirst = TRUE; // Silly cdrdao...
     }
     else if(!strcasecmp(args[0], "MODE1"))
     {
      TmpTrack.Format = TRACK_FORMAT_DATA;
      TmpTrack.IsData2352 = 0;
     }
     else if(!strcasecmp(args[0], "MODE1_RAW"))
     {
      TmpTrack.Format = TRACK_FORMAT_DATA;
      TmpTrack.IsData2352 = 1;
     }
    
     if(!strcasecmp(args[1], "RW"))
     {
      TmpTrack.SubchannelMode = CDRF_SUBM_RW;
      MDFN_printf(_("\"RW\" format subchannel data not supported, only \"RW_RAW\" is!\n"));
      free(ret);
      return(0);
     }
     else if(!strcasecmp(args[1], "RW_RAW"))
      TmpTrack.SubchannelMode = CDRF_SUBM_RW_RAW;

    } // end to TRACK
    else if(!strcasecmp(cmdbuf, "SILENCE"))
    {

    }
    else if(!strcasecmp(cmdbuf, "ZERO"))
    {

    }
    else if(!strcasecmp(cmdbuf, "FILE") || !strcasecmp(cmdbuf, "AUDIOFILE"))
    {
     const char *binoffset = NULL;
     const char *msfoffset = NULL;
     const char *length = NULL;

     if(args[1][0] == '#')
     {
      binoffset = args[1] + 1;
      msfoffset = args[2];
      length = args[3];
     }
     else
     {
      msfoffset = args[1];
      length = args[2];
     }
     //printf("%s, %s, %s, %s\n", args[0], binoffset, msfoffset, length);
     if(!ParseTOCFileLineInfo(&TmpTrack, active_track, args[0], binoffset, msfoffset, length))
     {
      free(ret);
      return(0);
     }
    }
    else if(!strcasecmp(cmdbuf, "DATAFILE"))
    {
     const char *binoffset = NULL;
     const char *length = NULL;
  
     if(args[1][0] == '#') 
     {
      binoffset = args[1] + 1;
      length = args[2];
     }
     else
      length = args[1];

     if(!ParseTOCFileLineInfo(&TmpTrack, active_track, args[0], binoffset, NULL, length))
     {
      free(ret);
      return(0);
     }
    }
    else if(!strcasecmp(cmdbuf, "INDEX"))
    {

    }
    else if(!strcasecmp(cmdbuf, "PREGAP"))
    {
     if(active_track < 0)
     {
      MDFN_printf(_("Command %s is outside of a TRACK definition!\n"), cmdbuf);
      free(ret);
      return(NULL);
     }
     int m,s,f;
     trio_sscanf(args[0], "%d:%d:%d", &m, &s, &f);
     TmpTrack.pregap = (m * 60 + s) * 75 + f;
    } // end to PREGAP
    else if(!strcasecmp(cmdbuf, "START"))
    {
     if(active_track < 0)
     {
      MDFN_printf(_("Command %s is outside of a TRACK definition!\n"), cmdbuf);
      free(ret);
      return(NULL);
     }
     int m,s,f;
     trio_sscanf(args[0], "%d:%d:%d", &m, &s, &f);
     TmpTrack.pregap = (m * 60 + s) * 75 + f;
    }
   } /*********** END TOC HANDLING ************/
   else // now for CUE sheet handling
   {
    if(!strcasecmp(cmdbuf, "FILE"))
    {
     if(active_track >= 0)
     {
      memcpy(&ret->Tracks[active_track], &TmpTrack, sizeof(TmpTrack));
      memset(&TmpTrack, 0, sizeof(TmpTrack));
      active_track = -1;
     }
     std::string efn = MDFN_MakeFName(MDFNMKF_AUX, 0, args[0]);
     if(NULL == (TmpTrack.fp = fopen(efn.c_str(), "rb")))
     {
      MDFN_printf(_("Could not open referenced file \"%s\": %m\n"), efn.c_str(), errno);
      free(ret);
      return(0);
     }
     TmpTrack.FirstFileInstance = 1;
     if(!strcasecmp(args[1], "BINARY"))
     {
      //TmpTrack.Format = TRACK_FORMAT_DATA;
      //struct stat stat_buf;
      //fstat(fileno(TmpTrack.fp), &stat_buf);
      //TmpTrack.sectors = stat_buf.st_size; // / 2048;
     }
     else if(!strcasecmp(args[1], "OGG") || !strcasecmp(args[1], "VORBIS") || !strcasecmp(args[1], "WAVE") || !strcasecmp(args[1], "WAV") || !strcasecmp(args[1], "PCM")
	|| !strcasecmp(args[1], "MPC") || !strcasecmp(args[1], "MP+"))
     {
      TmpTrack.ovfile = (OggVorbis_File *) calloc(1, sizeof(OggVorbis_File));

      if((TmpTrack.sf = sf_open_fd(fileno(TmpTrack.fp), SFM_READ, &TmpTrack.sfinfo, 0)))
      {
       free(TmpTrack.ovfile);
       TmpTrack.ovfile = NULL;
      }
      else if(!lseek(fileno(TmpTrack.fp), 0, SEEK_SET) && !ov_open(TmpTrack.fp, TmpTrack.ovfile, NULL, 0))
      {
       //TmpTrack.Format = TRACK_FORMAT_AUDIO;
       //TmpTrack.sectors = ov_pcm_total(&TmpTrack.ovfile, -1) / 588;
      }
      else
      {      
       free(TmpTrack.ovfile);
       TmpTrack.ovfile = NULL;

       fseek(TmpTrack.fp, 0, SEEK_SET);

       TmpTrack.MPCReaderFile = (mpc_reader_file *)calloc(1, sizeof(mpc_reader_file));
       TmpTrack.MPCStreamInfo = (mpc_streaminfo *)calloc(1, sizeof(mpc_streaminfo));
       TmpTrack.MPCDecoder = (mpc_decoder *)calloc(1, sizeof(mpc_decoder));
       TmpTrack.MPCBuffer = (MPC_SAMPLE_FORMAT *)calloc(MPC_DECODER_BUFFER_LENGTH, sizeof(MPC_SAMPLE_FORMAT));

       mpc_streaminfo_init(TmpTrack.MPCStreamInfo);

       mpc_reader_setup_file_reader(TmpTrack.MPCReaderFile, TmpTrack.fp);

       if(mpc_streaminfo_read(TmpTrack.MPCStreamInfo, &TmpTrack.MPCReaderFile->reader) != ERROR_CODE_OK)
       {
        MDFN_printf(_("Unsupported audio track file format: %s\n"), args[0]);
        free(TmpTrack.MPCReaderFile);
        free(TmpTrack.MPCStreamInfo);
        free(TmpTrack.MPCDecoder);
        free(TmpTrack.MPCBuffer);
        free(ret);
        return(0);
       }

       mpc_decoder_setup(TmpTrack.MPCDecoder, &TmpTrack.MPCReaderFile->reader);
       if(!mpc_decoder_initialize(TmpTrack.MPCDecoder, TmpTrack.MPCStreamInfo))
       {
        MDFN_printf(_("Error initializing MusePack decoder: %s!\n"), args[0]);
        free(TmpTrack.MPCReaderFile);
        free(TmpTrack.MPCStreamInfo);
        free(TmpTrack.MPCDecoder);
        free(TmpTrack.MPCBuffer);
        free(ret);
        return(0);
       }
      }
     }
     else
     {
      MDFN_printf(_("Unsupported track format: %s\n"), args[1]);
      free(ret);
      return(0);
     }
    }
    else if(!strcasecmp(cmdbuf, "TRACK"))
    {
     if(active_track >= 0)
     {
      memcpy(&ret->Tracks[active_track], &TmpTrack, sizeof(TmpTrack));
      TmpTrack.FirstFileInstance = 0;
      TmpTrack.pregap = 0;
     }
     active_track = atoi(args[0]);

     if(active_track < FirstTrack)
      FirstTrack = active_track;
     if(active_track > LastTrack)
      LastTrack = active_track;

     if(!strcasecmp(args[1], "AUDIO"))
      TmpTrack.Format = TRACK_FORMAT_AUDIO;
     else if(!strcasecmp(args[1], "MODE1/2048"))
     {
      TmpTrack.Format = TRACK_FORMAT_DATA;
      TmpTrack.IsData2352 = 0;
     }
     else if(!strcasecmp(args[1], "MODE1/2352"))
     {
      TmpTrack.Format = TRACK_FORMAT_DATA;
      TmpTrack.IsData2352 = 1;
     }
     TmpTrack.sectors = GetSectorCount(&TmpTrack);
     if(active_track < 0 || active_track > 99)
     {
      MDFN_printf(_("Invalid track number: %d\n"), active_track);
      return(0);
     }
    }
    else if(!strcasecmp(cmdbuf, "INDEX"))
    {
     if(active_track >= 0 && (!strcasecmp(args[0], "01") || !strcasecmp(args[0], "1")))
     {
      int m,s,f;
      trio_sscanf(args[1], "%d:%d:%d", &m, &s, &f);
      TmpTrack.index = (m * 60 + s) * 75 + f;
     }
    }
    else if(!strcasecmp(cmdbuf, "PREGAP"))
    {
     if(active_track >= 0)
     {
      int m,s,f;
      trio_sscanf(args[0], "%d:%d:%d", &m, &s, &f);
      TmpTrack.pregap = (m * 60 + s) * 75 + f;
     }
    }
   } // end of CUE sheet handling
  } // end of fgets() loop

 if(ferror(fp))
 {
  if(IsTOC)
   MDFN_printf(_("Error reading TOC file: %m\n"), errno);
  else
   MDFN_printf(_("Error reading CUE sheet: %m\n"), errno);
  return(0);
 }

 if(active_track >= 0)
  memcpy(&ret->Tracks[active_track], &TmpTrack, sizeof(TmpTrack));
 
 if(FirstTrack > LastTrack)
 {
  MDFN_printf(_("No tracks found!\n"));
  return(0);
 }

 ret->FirstTrack = FirstTrack;
 ret->NumTracks = 1 + LastTrack - FirstTrack;

 lsn_t RunningLSN = 0;
 lsn_t LastIndex = 0;
 long FileOffset = 0;

 for(int x = ret->FirstTrack; x < (ret->FirstTrack + ret->NumTracks); x++)
 {
  if(IsTOC)
  {
   RunningLSN += ret->Tracks[x].pregap;
   ret->Tracks[x].LSN = RunningLSN;
   RunningLSN += ret->Tracks[x].sectors;
  }
  else // else handle CUE sheet...
  {
   if(ret->Tracks[x].FirstFileInstance) 
   {
    LastIndex = 0;
    FileOffset = 0;
   }
   RunningLSN += ret->Tracks[x].pregap;

   ret->Tracks[x].LSN = RunningLSN;

   // Make sure this is set before the call to GetSectorCount() for the last track sector count fix.
   ret->Tracks[x].FileOffset = FileOffset;

   if((x + 1) >= (ret->FirstTrack + ret->NumTracks))
   {
    if(!(ret->Tracks[x].FirstFileInstance))
    {
     // This will fix the last sector count for CUE+BIN
     ret->Tracks[x].sectors = GetSectorCount(&ret->Tracks[x]);
    }
   }
   else if(ret->Tracks[x+1].FirstFileInstance)
   {
    //RunningLSN += ret->Tracks[x].sectors;
   }
   else
   { 
    // Fix the sector count if we're CUE+BIN
    ret->Tracks[x].sectors = ret->Tracks[x + 1].index - ret->Tracks[x].index;
   }

   //printf("Poo: %d %d\n", x, ret->Tracks[x].sectors);
   RunningLSN += ret->Tracks[x].sectors;

   //printf("%d, %ld %d %d %d %d\n", x, FileOffset, ret->Tracks[x].index, ret->Tracks[x].pregap, ret->Tracks[x].sectors, ret->Tracks[x].LSN);

   if(ret->Tracks[x].Format == TRACK_FORMAT_AUDIO || TmpTrack.IsData2352)
    FileOffset += ret->Tracks[x].sectors * 2352;
   else
    FileOffset += ret->Tracks[x].sectors * 2048;
  } // end to cue sheet handling
 } // end to track loop

 LEC_Eval = MDFN_GetSettingB("cdrom.lec_eval");
 if(LEC_Eval)
 {
  Init_LEC_Correct();
 }
 MDFN_printf(_("Raw rip data correction using L-EC: %s\n\n"), LEC_Eval ? _("Enabled") : _("Disabled"));

 ret->total_sectors = RunningLSN; // Running LBA?  Running LSN? arghafsdf...LSNBAN!#!$ -_-
 return(ret);
}
Пример #15
0
bool MDFNFILE::ApplyIPS(FILE *ips)
{
 uint8 header[5];
 uint32 count = 0;
 
 //MDFN_printf(_("Applying IPS file \"%s\"...\n"), path);

 MDFN_indent(1);
 if(::fread(header, 1, 5, ips) != 5)
 {
  ErrnoHolder ene(errno);

  MDFN_PrintError(_("Error reading IPS file header: %s"), ene.StrError());
  MDFN_indent(-1);
  return(0);
 }

 if(memcmp(header, "PATCH", 5))
 {
  MDFN_PrintError(_("IPS file header is invalid."));
  MDFN_indent(-1);
  return(0);
 }

 #ifdef HAVE_MMAP
 // If the file is mmap()'d, move it to malloc()'d RAM
 if(is_mmap)
 {
  void *tmp_ptr = MDFN_malloc(f_size, _("file read buffer"));
  if(!tmp_ptr)
  {
   //Close();
   //fclose(ipsfile);
   return(0);
  }
  memcpy(tmp_ptr, f_data, f_size);

  munmap(f_data, f_size);

  is_mmap = FALSE;
  f_data = (uint8 *)tmp_ptr;
 }
 #endif

 while(::fread(header, 1, 3, ips) == 3)
 {
  uint32 offset = (header[0] << 16) | (header[1] << 8) | header[2];
  uint8 patch_size_raw[2];
  uint32 patch_size;
  bool rle = false;

  if(!memcmp(header, "EOF", 3))
  {
   MDFN_printf(_("IPS EOF:  Did %d patches\n\n"), count);
   MDFN_indent(-1);
   return(1);
  }

  if(::fread(patch_size_raw, 1, 2, ips) != 2)
  {
   ErrnoHolder ene(errno);
   MDFN_PrintError(_("Error reading IPS patch length: %s"), ene.StrError());
   return(0);
  }

  patch_size = MDFN_de16msb(patch_size_raw);

  if(!patch_size)	/* RLE */
  {
   if(::fread(patch_size_raw, 1, 2, ips) != 2)
   {
    ErrnoHolder ene(errno);
    MDFN_PrintError(_("Error reading IPS RLE patch length: %s"), ene.StrError());
    return(0);
   }

   patch_size = MDFN_de16msb(patch_size_raw);

   // Is this right?
   if(!patch_size)
    patch_size = 65536;

   rle = true;
   //MDFN_printf("  Offset: %8d  Size: %5d RLE\n",offset, patch_size);
  }

  if((offset + patch_size) > f_size)
  {
   uint8 *tmp;

   //printf("%d\n", offset + patch_size, f_size);

   if((offset + patch_size) > MaxROMImageSize)
   {
    MDFN_PrintError(_("ROM image will be too large after IPS patch; maximum size allowed is %llu bytes."), (unsigned long long)MaxROMImageSize);
    return(0);
   }

   if(!(tmp = (uint8 *)MDFN_realloc(f_data, offset + patch_size, _("file read buffer"))))
    return(0);

   // Zero newly-allocated memory
   memset(tmp + f_size, 0, (offset + patch_size) - f_size);

   f_size = offset + patch_size;
   f_data = tmp;
  }


  if(rle)
  {
   const int b = ::fgetc(ips);
   uint8 *start = f_data + offset;

   if(EOF == b)
   {
    ErrnoHolder ene(errno);

    MDFN_PrintError(_("Error reading IPS RLE patch byte: %s"), ene.StrError());

    return(0);
   }

   while(patch_size--)
   {
    *start=b;
    start++;
   }

  }
  else		/* Normal patch */
  {
   //MDFN_printf("  Offset: %8d  Size: %5d\n", offset, patch_size);
   if(::fread(f_data + offset, 1, patch_size, ips) != patch_size)
   {
    ErrnoHolder ene(errno);

    MDFN_PrintError(_("Error reading IPS patch: %s"), ene.StrError());
    return(0);
   }
  }
  count++;
 }
 ErrnoHolder ene(errno);

 //MDFN_printf(_("Warning:  IPS ended without an EOF chunk.\n"));
 //MDFN_printf(_("IPS EOF:  Did %d patches\n\n"), count);
 MDFN_indent(-1);

 MDFN_PrintError(_("Error reading IPS patch header: %s"), ene.StrError());
 return(0);

 //return(1);
}
Пример #16
0
/* Rectangle, left, right(not inclusive), top, bottom(not inclusive). */
OpenGL_Blitter::OpenGL_Blitter(int scanlines, ShaderType pixshader, const int screen_w, const int screen_h, int *rs, int *gs, int *bs, int *as) : gl_screen_w(screen_w), gl_screen_h(screen_h)
{
 try
 {
 const char *extensions;
 const char *vendor;
 const char *renderer;
 const char *version;
 uint32 version_h;

 MaxTextureSize = 0;
 SupportNPOT = false;
 SupportARBSync = false;
 PixelFormat = 0;
 PixelType = 0;

 for(unsigned i = 0; i < 4; i++)
  textures[i] = 0;

 rgb_mask = 0;

 using_scanlines = 0;
 last_w = 0;
 last_h = 0;

 OSDLastWidth = 0;
 OSDLastHeight = 0;

 shader = NULL;

 DummyBlack = NULL;
 DummyBlackSize = 0;


 #define LFG(x) if(!(p_##x = (x##_Func) SDL_GL_GetProcAddress(#x))) { throw MDFN_Error(0, _("Error getting proc address for: %s\n"), #x); }
 #define LFGN(x) p_##x = (x##_Func) SDL_GL_GetProcAddress(#x)

 LFG(glGetError);
 LFG(glBindTexture);
 LFGN(glColorTableEXT);
 LFG(glTexImage2D);
 LFG(glBegin);
 LFG(glVertex2f);
 LFG(glTexCoord2f);
 LFG(glEnd);
 LFG(glEnable);
 LFG(glBlendFunc);
 LFG(glGetString);
 LFG(glViewport);
 LFG(glGenTextures);
 LFG(glDeleteTextures);
 LFG(glTexParameteri);
 LFG(glClearColor);
 LFG(glLoadIdentity);
 LFG(glClear);
 LFG(glMatrixMode);
 LFG(glDisable);
 LFG(glPixelStorei);
 LFG(glTexSubImage2D);
 LFG(glFinish);
 LFG(glOrtho);
 LFG(glPixelTransferf);
 LFG(glColorMask);
 LFG(glTexEnvf);
 LFG(glGetIntegerv);
 LFG(glTexGend);
 LFG(glRasterPos2i);
 LFG(glDrawPixels);
 LFG(glPixelZoom);
 LFG(glAccum);
 LFG(glClearAccum);
 LFG(glGetTexLevelParameteriv);
 LFG(glPushMatrix);
 LFG(glPopMatrix);
 LFG(glRotated);
 LFG(glScalef);
 LFG(glReadPixels);

 vendor = (const char *)p_glGetString(GL_VENDOR);
 renderer = (const char *)p_glGetString(GL_RENDERER);
 version = (const char *)p_glGetString(GL_VERSION);

 {
  int major = 0, minor = 0;
  trio_sscanf(version, "%d.%d", &major, &minor);
  if(minor < 0) minor = 0;
  if(minor > 255) minor = 255;

  version_h = (major << 8) | minor;
  //printf("%08x\n", version_h);
 }

 MDFN_printf(_("OpenGL Implementation: %s %s %s\n"), vendor, renderer, version);

 extensions = (const char*)p_glGetString(GL_EXTENSIONS);

 MDFN_printf(_("Checking extensions:\n"));
 MDFN_indent(1);

 SupportNPOT = FALSE;
 SupportARBSync = false;

 if(CheckExtension(extensions, "GL_ARB_texture_non_power_of_two"))
 {
  MDFN_printf(_("GL_ARB_texture_non_power_of_two found.\n"));
  SupportNPOT = TRUE;
 }

 if(CheckExtension(extensions, "GL_ARB_sync"))
 {
  MDFN_printf(_("GL_ARB_sync found.\n"));
  LFG(glFenceSync);
  LFG(glIsSync);
  LFG(glDeleteSync);
  LFG(glClientWaitSync);
  LFG(glWaitSync);
  LFG(glGetInteger64v);
  LFG(glGetSynciv);
  SupportARBSync = true;
 }

 MDFN_indent(-1);

 // x,y specify LOWER left corner of the viewport.
 p_glViewport(0, 0, gl_screen_w, gl_screen_h);

 p_glGenTextures(4, &textures[0]);
 p_glGenTextures(1, &rgb_mask);
 using_scanlines = 0;

 shader = NULL;

 if(pixshader != SHADER_NONE)
 {
  LFG(glCreateShaderObjectARB);
  LFG(glShaderSourceARB);
  LFG(glCompileShaderARB);
  LFG(glCreateProgramObjectARB);
  LFG(glAttachObjectARB);
  LFG(glLinkProgramARB);
  LFG(glUseProgramObjectARB);
  LFG(glUniform1fARB);
  LFG(glUniform2fARB);
  LFG(glUniform3fARB);
  LFG(glUniform1iARB);
  LFG(glUniform2iARB);
  LFG(glUniform3iARB);
  LFG(glUniformMatrix2fvARB);
  LFG(glActiveTextureARB);
  LFG(glGetInfoLogARB);
  LFG(glGetUniformLocationARB);
  LFG(glDeleteObjectARB);
  LFG(glDetachObjectARB);

  LFG(glGetObjectParameterivARB);

  shader = new OpenGL_Blitter_Shader(this, pixshader);
  SupportNPOT = 0; 	 // Our pixel shaders don't work right with NPOT textures(for them to do so would probably necessitate rewriting them to use texelFetch)
  p_glActiveTextureARB(GL_TEXTURE0_ARB);
 }

 // printf here because pixel shader code will set SupportNPOT to 0

 if(SupportNPOT)
  MDFN_printf(_("Using non-power-of-2 sized textures.\n"));
 else
  MDFN_printf(_("Using power-of-2 sized textures.\n"));

 if(scanlines)
 {
  int slcount;

  using_scanlines = scanlines;

  p_glBindTexture(GL_TEXTURE_2D, textures[1]);
  p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
  p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

  uint8 *buf=(uint8*)malloc(64 * (256 * 2) * 4);

  slcount = 0;
  for(int y=0;y<(256 * 2);y++)
  {
   for(int x=0;x<64;x++)
   {
    int sl_alpha;

    if(slcount)
     sl_alpha = 0xFF - (0xFF * abs(scanlines) / 100);
    else
     sl_alpha = 0xFF;

    buf[y*64*4+x*4]=0;
    buf[y*64*4+x*4+1]=0;
    buf[y*64*4+x*4+2]=0;
    buf[y*64*4+x*4+3] = sl_alpha;
    //buf[y*256+x]=(y&1)?0x00:0xFF;
   }
   slcount ^= 1;
  }
  p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 64);
  p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 64, 256 * 2, 0, GL_RGBA,GL_UNSIGNED_BYTE,buf);
  free(buf);
 }
 p_glBindTexture(GL_TEXTURE_2D, textures[3]);
 p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
 p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
 p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
 p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);


 p_glBindTexture(GL_TEXTURE_2D, textures[0]);
     
 p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
 p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 //p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 0x812F);
 //p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 0x812F);

 p_glBindTexture(GL_TEXTURE_2D, textures[2]);

 p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
 p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);

 p_glEnable(GL_TEXTURE_2D);
 p_glClearColor(0.0f, 0.0f, 0.0f, 0.0f);	// Background color to black.
 p_glMatrixMode(GL_MODELVIEW);

 p_glLoadIdentity();
 p_glFinish();

 p_glDisable(GL_TEXTURE_1D);
 p_glDisable(GL_FOG);
 p_glDisable(GL_LIGHTING);
 p_glDisable(GL_LOGIC_OP);
 p_glDisable(GL_DITHER);
 p_glDisable(GL_COLOR_MATERIAL);
 p_glDisable(GL_NORMALIZE);
 p_glDisable(GL_SCISSOR_TEST);
 p_glDisable(GL_STENCIL_TEST);
 p_glDisable(GL_ALPHA_TEST);
 p_glDisable(GL_DEPTH_TEST);

 p_glPixelTransferf(GL_RED_BIAS, 0);
 p_glPixelTransferf(GL_GREEN_BIAS, 0);
 p_glPixelTransferf(GL_BLUE_BIAS, 0);
 p_glPixelTransferf(GL_ALPHA_BIAS, 0);

 p_glPixelTransferf(GL_RED_SCALE, 1);
 p_glPixelTransferf(GL_GREEN_SCALE, 1);
 p_glPixelTransferf(GL_BLUE_SCALE, 1);
 p_glPixelTransferf(GL_ALPHA_SCALE, 1);

 p_glPixelTransferf(GL_MAP_COLOR, GL_FALSE);

 p_glOrtho(0, gl_screen_w, gl_screen_h, 0, -1.0, 1.0);

 last_w = 0;
 last_h = 0;

 OSDLastWidth = OSDLastHeight = 0;


 MDFN_printf(_("Checking maximum texture size...\n"));
 MDFN_indent(1);
 p_glBindTexture(GL_TEXTURE_2D, textures[0]);
 // Assume maximum texture width is the same as maximum texture height to greatly simplify things
 MaxTextureSize = 32768;
 
 while(MaxTextureSize)
 {
  GLint width_test = 0;

  p_glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, MaxTextureSize, MaxTextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  p_glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width_test);

  if((unsigned int)width_test == MaxTextureSize)
   break;

  MaxTextureSize >>= 1;
 }
 MDFN_printf(_("Apparently it is at least: %d x %d\n"), MaxTextureSize, MaxTextureSize);

 if(MaxTextureSize < 256)
 {
  MDFN_printf(_("Warning:  Maximum texture size is reported as being less than 256, but we can't handle that.\n"));
  MaxTextureSize = 256;
 }

 DummyBlack = NULL;
 DummyBlackSize = 0;

 MDFN_indent(-1);

 if(!CheckAlternateFormat(version_h))
 {
  #ifdef LSB_FIRST
  *rs = 0;
  *gs = 8;
  *bs = 16;
  *as = 24;
  #else
  *rs = 24;
  *gs = 16;
  *bs = 8;
  *as = 0;
  #endif
  PixelFormat = GL_RGBA;
  PixelType = GL_UNSIGNED_BYTE;
  MDFN_printf(_("Using GL_RGBA, GL_UNSIGNED_BYTE for texture source data.\n"));
 }
 else
 {
  *as = 24;
  *rs = 16;
  *gs = 8;
  *bs = 0;
  PixelFormat = GL_BGRA;
  PixelType = GL_UNSIGNED_INT_8_8_8_8_REV;
  MDFN_printf(_("Using GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV for texture source data.\n"));
 }
 }
 catch(...)
 {
  Cleanup();
  throw;
 }
}
Пример #17
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);
}