示例#1
0
static int Load(const char *name, MDFNFILE *fp)
{
	LoadFunction_t LoadFunction = NULL;

	LoadFunction = GetLoadFunctionByMagic(name, fp);

	// If the file type isn't recognized, return -1!
	if(!LoadFunction)
	 return(-1);

	InitCommon(name);

	if(!LoadFunction(name, fp, GameInterface))
	{
	 free(GameInterface);
	 GameInterface = NULL;
	 return(0);
	}

	{
	 int w;

	 if(MDFNGameInfo->VideoSystem == VIDSYS_NTSC)
	  w = 0;
	 else if(MDFNGameInfo->VideoSystem == VIDSYS_PAL)
	  w = 1;
	 else
	 {
	  w = MDFN_GetSettingB("nes.pal");
	  MDFNGameInfo->VideoSystem = w ? VIDSYS_PAL : VIDSYS_NTSC;
	 }
	 PAL=w?1:0;
	 MDFNGameInfo->fps = PAL? 838977920 : 1008307711;
	 MDFNGameInfo->MasterClock = MDFN_MASTERCLOCK_FIXED(PAL ? PAL_CPU : NTSC_CPU);
	}

	X6502_Init();
	MDFNPPU_Init();
        MDFNSND_Init(PAL);
	NESINPUT_Init();

	if(NESIsVSUni)
	 MDFN_VSUniInstallRWHooks();


	if(MDFNGameInfo->GameType != GMT_PLAYER)
         if(MDFN_GetSettingB("nes.gg"))
	  Genie_Init();

        PowerNES();

        MDFN_InitPalette(NESIsVSUni ? MDFN_VSUniGetPaletteNum() : 0);

        return(1);
}
示例#2
0
文件: vblur.cpp 项目: ben401/OpenEmu
void VBlur_Init(void)
{
        std::string sn = MDFNGameInfo->shortname;

        if(MDFN_GetSettingB(std::string(sn + "." + std::string("vblur")).c_str()))
        {
         AccumBlurAmount = (uint32)(16384 * MDFN_GetSettingF(std::string(sn + "." + std::string("vblur.accum.amount")).c_str()) / 100);
         if(MDFN_GetSettingB(std::string(sn + "." + std::string("vblur.accum")).c_str()))
         {
          AccumBlurBuf = (HQPixelEntry *)calloc(sizeof(HQPixelEntry), (MDFNGameInfo->pitch >> 2) * 256);
          MDFN_printf(_("Video frame blur enabled with accumulation: %f.\n"), (double)AccumBlurAmount * 100 / 16384);
         }
示例#3
0
文件: main.cpp 项目: ben401/OpenEmu
int LoadGame(const char *path)
{
	MDFNGI *tmp;

	CloseGame();

	pending_save_state = 0;
	pending_save_movie = 0;
	pending_snapshot = 0;

	#ifdef NEED_CDEMU
	if(loadcd)
	{
	 if(!(tmp = MDFNI_LoadCD(loadcd, path)))
		return(0);
	}
	else
	#endif
	{
         if(!(tmp=MDFNI_LoadGame(path)))
	  return 0;
	}
	CurGame = tmp;
	InitGameInput(tmp);

        RefreshThrottleFPS(1);

        SDL_mutexP(VTMutex);
        NeedVideoChange = -1;
        SDL_mutexV(VTMutex);

        if(SDL_ThreadID() != MainThreadID)
          while(NeedVideoChange)
	  {
           SDL_Delay(1);
	  }
	sound_active = 0;

	if(MDFN_GetSettingB("sound"))
	 sound_active = InitSound(tmp);

        if(MDFN_GetSettingB("autosave"))
	 MDFNI_LoadState(NULL, "ncq");

	if(netconnect)
	 MDFND_NetworkConnect();

	GameThreadRun = 1;
	GameThread = SDL_CreateThread(GameLoop, NULL);

	ffnosound = MDFN_GetSettingB("ffnosound");
	return 1;
}
示例#4
0
static int Load(const char *name, MDFNFILE *fp)
{
   lynxie = new CSystem(GET_FDATA_PTR(fp), GET_FSIZE_PTR(fp));

 int rot = lynxie->CartGetRotate();
 if(rot == CART_ROTATE_LEFT) MDFNGameInfo->rotated = MDFN_ROTATE270;
 else if(rot == CART_ROTATE_RIGHT) MDFNGameInfo->rotated = MDFN_ROTATE90;

 gAudioEnabled = 1;

 memcpy(MDFNGameInfo->MD5, lynxie->mCart->MD5, 16);
 MDFNGameInfo->GameSetMD5Valid = FALSE;

 MDFN_printf(_("ROM:       %dKiB\n"), (lynxie->mCart->InfoROMSize + 1023) / 1024);
 MDFN_printf(_("ROM CRC32: 0x%08x\n"), lynxie->mCart->CRC32());
 MDFN_printf(_("ROM MD5:   0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());

 MDFNGameInfo->fps = (uint32)(59.8 * 65536 * 256);

 if(MDFN_GetSettingB("lynx.lowpass"))
 {
  lynxie->mMikie->miksynth.treble_eq(-35);
 }
 else
 {
  lynxie->mMikie->miksynth.treble_eq(0);
 }
 return(1);
}
示例#5
0
static void LoadCommon(MDFNFILE *fp)
{
 try
 {
  /* Assign default settings (US NTSC machine) */
  sms.display     = DISPLAY_NTSC;

  sms.territory   = MDFN_GetSettingI("sms.territory");
  sms.use_fm      = FALSE;

  Cart_Init(fp);
  Cart_LoadNV();

  if(IS_SMS && sms.territory == TERRITORY_DOMESTIC)
   sms.use_fm = MDFN_GetSettingB("sms.fm");

  MDFNMP_Init(1024, 65536 / 1024);

  system_assign_device(PORT_A, DEVICE_PAD2B);
  system_assign_device(PORT_B, DEVICE_PAD2B);

  MDFNMP_AddRAM(8192, 0xC000, sms.wram);

  sms_init();
  pio_init();
  vdp_init(IS_SMS && sms.territory == TERRITORY_DOMESTIC);
  render_init();

  MDFNGameInfo->GameSetMD5Valid = FALSE;

  uint32 sndclk;

  if(sms.display == DISPLAY_PAL)
  {
   sndclk = 3546893;
   MDFNGameInfo->fps = (uint32)((uint64)65536 * 256 * sndclk / 313 / 228); //6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198
  }
  else
  {
   sndclk = 3579545;
   MDFNGameInfo->fps = (uint32)((uint64)65536 * 256 * sndclk / 262 / 228); //6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198
  }

  MDFNGameInfo->MasterClock = MDFN_MASTERCLOCK_FIXED(sndclk);

  SMS_SoundInit(sndclk, sms.use_fm);

  sms.save = 0;

  system_reset();
 }
 catch(...)
 {
  Cleanup();
  throw;
 }
}
示例#6
0
static void InitCommon(const char *name)
{
        NESIsVSUni = FALSE;
        PPU_hook = 0;
        GameHBIRQHook = 0;

        MapIRQHook = 0;
        MMC5Hack = 0;
        PAL &= 1;

        MDFNGameInfo->GameType = GMT_CART;
        MDFNGameInfo->VideoSystem = VIDSYS_NONE;

        MDFNGameInfo->cspecial = NULL;
        MDFNGameInfo->GameSetMD5Valid = FALSE;


        if(MDFN_GetSettingB("nes.fnscan"))
        {
	 const char *fn = GetFNComponent(name);	// TODO: This seems awfully spaghetti-like/inefficient.  Fixme?

         if(strstr(fn, "(U)") || strstr(fn, "(USA)"))
          MDFNGameInfo->VideoSystem = VIDSYS_NTSC;
         else if(strstr(fn, "(J)") || strstr(fn, "(Japan)"))
          MDFNGameInfo->VideoSystem = VIDSYS_NTSC;
         else if(strstr(fn, "(E)") || strstr(fn, "(G)") || strstr(fn, "(Europe)") || strstr(fn, "(Germany)") )
          MDFNGameInfo->VideoSystem = VIDSYS_PAL;
        }

        GameInterface = (NESGameType *)calloc(1, sizeof(NESGameType));

        SetReadHandler(0x0000, 0xFFFF, ANull);
        SetWriteHandler(0x0000, 0xFFFF, BNull);

        SetReadHandler(0x10000,0x10000 + 0xFF, AOverflow);
        SetWriteHandler(0x10000,0x10000 + 0xFF, BOverflow);

        SetReadHandler(0,0x7FF,ARAML);
        SetWriteHandler(0,0x7FF,BRAML);

        SetReadHandler(0x800,0x1FFF,ARAMH);  /* Part of a little */
        SetWriteHandler(0x800,0x1FFF,BRAMH); /* hack for a small speed boost. */

        MDFNMP_Init(1024, 65536 / 1024);


	#ifdef WANT_DEBUGGER
	NESDBG_Init();

        ASpace_Add(NESDBG_GetAddressSpaceBytes, NESDBG_PutAddressSpaceBytes, "cpu", "CPU", 16);
        ASpace_Add(NESPPU_GetAddressSpaceBytes, NESPPU_PutAddressSpaceBytes, "ppu", "PPU", 14);
        #endif
}
示例#7
0
static MDFN_COLD void InitCommon(const std::string& fbase)
{
        NESIsVSUni = false;
        PPU_hook = 0;
        GameHBIRQHook = 0;

        MapIRQHook = 0;
        MMC5Hack = 0;
        PAL &= 1;

        MDFNGameInfo->VideoSystem = VIDSYS_NONE;

        MDFNGameInfo->cspecial = NULL;

        if(MDFN_GetSettingB("nes.fnscan"))
        {
         if(fbase.find("(U)") != std::string::npos || fbase.find("(USA)") != std::string::npos)
          MDFNGameInfo->VideoSystem = VIDSYS_NTSC;
         else if(fbase.find("(J)") != std::string::npos || fbase.find("(Japan)") != std::string::npos)
          MDFNGameInfo->VideoSystem = VIDSYS_NTSC;
         else if(fbase.find("(E)") != std::string::npos || fbase.find("(G)") != std::string::npos || fbase.find("(F)") != std::string::npos ||
	         fbase.find("(Europe)") != std::string::npos || fbase.find("(Germany)") != std::string::npos || fbase.find("(France)") != std::string::npos)
          MDFNGameInfo->VideoSystem = VIDSYS_PAL;
        }

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

        SetReadHandler(0x0000, 0xFFFF, ANull);
        SetWriteHandler(0x0000, 0xFFFF, BNull);

        SetReadHandler(0x10000,0x10000 + 0xFF, AOverflow);
        SetWriteHandler(0x10000,0x10000 + 0xFF, BOverflow);

        SetReadHandler(0,0x7FF,ARAML);
        SetWriteHandler(0,0x7FF,BRAML);

        SetReadHandler(0x800,0x1FFF,ARAMH);  /* Part of a little */
        SetWriteHandler(0x800,0x1FFF,BRAMH); /* hack for a small speed boost. */

        MDFNMP_Init(1024, 65536 / 1024);


	#ifdef WANT_DEBUGGER
	NESDBG_Init();

	ASpace_Add(NESDBG_GetAddressSpaceBytes, NESDBG_PutAddressSpaceBytes, "cpu", "CPU", 16);
	ASpace_Add(NESPPU_GetAddressSpaceBytes, NESPPU_PutAddressSpaceBytes, "ppu", "PPU", 14);
	ASpace_Add(NESPPU_GetAddressSpaceBytes, NESPPU_PutAddressSpaceBytes, "spram", "Sprite RAM", 8);
        #endif
}
示例#8
0
static void Load(MDFNFILE *fp)
{
 try
 {
  lynxie = new CSystem(fp);

  switch(lynxie->CartGetRotate())
  {
   case CART_ROTATE_LEFT:
	MDFNGameInfo->rotated = MDFN_ROTATE270;
	break;

   case CART_ROTATE_RIGHT:
	MDFNGameInfo->rotated = MDFN_ROTATE90;
	break;
  }

  MDFNGameInfo->GameSetMD5Valid = false;
  if(lynxie->mRam->InfoRAMSize)
  {
   memcpy(MDFNGameInfo->MD5, lynxie->mRam->MD5, 16);
   MDFN_printf(_("RAM:       %u bytes\n"), lynxie->mRam->InfoRAMSize);
   MDFN_printf(_("RAM MD5:   0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());
  }
  else
  {
   memcpy(MDFNGameInfo->MD5, lynxie->mCart->MD5, 16);
   MDFN_printf(_("ROM:       %dKiB\n"), (lynxie->mCart->InfoROMSize + 1023) / 1024);
   MDFN_printf(_("ROM MD5:   0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());
  }

  MDFNGameInfo->fps = (uint32)(59.8 * 65536 * 256);

  if(MDFN_GetSettingB("lynx.lowpass"))
  {
   lynxie->mMikie->miksynth.treble_eq(-35);
  }
  else
  {
   lynxie->mMikie->miksynth.treble_eq(0);
  }
 }
 catch(std::exception &e)
 {
  Cleanup();

  throw;
 }
}
示例#9
0
static int Load(const char *name, MDFNFILE *fp)
{
 try
 {
  lynxie = new CSystem(fp->data, fp->size);

  switch(lynxie->CartGetRotate())
  {
   case CART_ROTATE_LEFT:
	MDFNGameInfo->rotated = MDFN_ROTATE270;
	break;

   case CART_ROTATE_RIGHT:
	MDFNGameInfo->rotated = MDFN_ROTATE90;
	break;
  }

  memcpy(MDFNGameInfo->MD5, lynxie->mCart->MD5, 16);
  MDFNGameInfo->GameSetMD5Valid = FALSE;

  MDFN_printf(_("ROM:       %dKiB\n"), (lynxie->mCart->InfoROMSize + 1023) / 1024);
  MDFN_printf(_("ROM CRC32: 0x%08x\n"), lynxie->mCart->CRC32());
  MDFN_printf(_("ROM MD5:   0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());

  MDFNGameInfo->fps = (uint32)(59.8 * 65536 * 256);

  if(MDFN_GetSettingB("lynx.lowpass"))
  {
   lynxie->mMikie->miksynth.treble_eq(-35);
  }
  else
  {
   lynxie->mMikie->miksynth.treble_eq(0);
  }
 }
 catch(std::exception &e)
 {
  MDFN_PrintError("%s", e.what());

  Cleanup();

  return(0);
 }

 return(1);
}
示例#10
0
// Called from main thread
int NetplayEventHook(const SDL_Event *event)
{
 if(event->type == SDL_USEREVENT)
  switch(event->user.code)
  {
   case CEVT_NP_LINE_RESPONSE:
	{
	 inputable = (event->user.data1 != NULL);
         if(event->user.data2 != NULL)
	 {
	  viewable = true;
          LastTextTime = SDL_GetTicks();
	 }
	}
	break;

   case CEVT_NP_TOGGLE_TT:
	NetConsole.SetFont(MDFN_GetSettingB("netplay.smallfont") ? MDFN_FONT_5x7 : MDFN_FONT_9x18_18x18);	// FIXME: Setting manager mutex needed example!
	if(viewable && !inputable)
	{
	 inputable = TRUE;
	}
	else
	{
	 viewable = !viewable;
	 inputable = viewable;
	}
	break;

   case CEVT_NP_DISPLAY_TEXT:
	NetConsole.WriteLine((UTF8*)event->user.data1);
	free(event->user.data1);

	if(!(bool)event->user.data2)
	{
	 viewable = 1;
	 LastTextTime = SDL_GetTicks();
	}
	break;
  }

 if(!inputable)
  return(1);

 return(NetConsole.Event(event));
}
示例#11
0
void PCE_InitCD(void)
{
 PCECD_Settings cd_settings;
 memset(&cd_settings, 0, sizeof(PCECD_Settings));

 cd_settings.CDDA_Volume = (double)MDFN_GetSettingUI("pce_fast.cddavolume") / 100;
 cd_settings.CD_Speed = MDFN_GetSettingUI("pce_fast.cdspeed");

 cd_settings.ADPCM_Volume = (double)MDFN_GetSettingUI("pce_fast.adpcmvolume") / 100;
 cd_settings.ADPCM_LPF = MDFN_GetSettingB("pce_fast.adpcmlp");

 if(cd_settings.CDDA_Volume != 1.0)
  MDFN_printf(_("CD-DA Volume: %d%%\n"), (int)(100 * cd_settings.CDDA_Volume));

 if(cd_settings.ADPCM_Volume != 1.0)
  MDFN_printf(_("ADPCM Volume: %d%%\n"), (int)(100 * cd_settings.ADPCM_Volume));

 PCECD_Init(&cd_settings, PCECDIRQCB, PCE_MASTER_CLOCK, pce_overclocked, sbuf);
}
示例#12
0
static void system_init(bool overseas, bool PAL, bool overseas_reported, bool PAL_reported)
{
    gen_running = 1;

    z80_init();
    z80_readbyte = MD_Z80_ReadByte;
    z80_writebyte = MD_Z80_WriteByte;
    z80_readport = MD_Z80_ReadPort;
    z80_writeport = MD_Z80_WritePort;

    gen_init();
    MDIO_Init(overseas, PAL, overseas_reported, PAL_reported);
    MainVDP.SetSettings(PAL, PAL_reported, MDFN_GetSettingB("md.correct_aspect"));

#ifdef WANT_DEBUGGER
    MDDBG_Init();
#endif

}
示例#13
0
bool CDIF_Open(const char *device_name)
{
 CDIF_Message msg;

 ReadThreadQueue = new CDIF_Queue();
 EmuThreadQueue = new CDIF_Queue();
 
 SBMutex = MDFND_CreateMutex();
 SectorBuffers = (CDIF_Sector_Buffer *)calloc(SBSize, sizeof(CDIF_Sector_Buffer));

 SBWritePos = 0;
 ra_lba = 0;
 ra_count = 0;
 last_read_lba = -1;

 CDReadThread = MDFND_CreateThread(ReadThreadStart, device_name ? strdup(device_name) : NULL);

 EmuThreadQueue->Read(&msg);

 if(!msg.args[0])
 {
  MDFND_WaitThread(CDReadThread, NULL);
  delete ReadThreadQueue;
  delete EmuThreadQueue;

  ReadThreadQueue = NULL;
  EmuThreadQueue = NULL;

  return(FALSE);
 }

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

 return(TRUE);
}
示例#14
0
static void LoadCommonPre(void)
{
 // FIXME:  Make these globals less global!
 pce_overclocked = MDFN_GetSettingUI("pce_fast.ocmultiplier");
 PCE_ACEnabled = MDFN_GetSettingB("pce_fast.arcadecard");

 if(pce_overclocked > 1)
  MDFN_printf(_("CPU overclock: %dx\n"), pce_overclocked);

 if(MDFN_GetSettingUI("pce_fast.cdspeed") > 1)
  MDFN_printf(_("CD-ROM speed:  %ux\n"), (unsigned int)MDFN_GetSettingUI("pce_fast.cdspeed"));

 memset(HuCPUFastMap, 0, sizeof(HuCPUFastMap));
 for(int x = 0; x < 0x100; x++)
 {
  PCERead[x] = PCEBusRead;
  PCEWrite[x] = PCENullWrite;
 }

 MDFNMP_Init(1024, (1 << 21) / 1024);
}
示例#15
0
文件: main.cpp 项目: ben401/OpenEmu
bool MT_FromRemote_SoundSync(void)
{
 bool ret = TRUE;

 GameThreadRun = 0;
 SDL_WaitThread(GameThread, NULL);

 KillSound();
 sound_active = 0;

 if(MDFN_GetSettingB("sound"))
 {
  sound_active = InitSound(CurGame);
  if(!sound_active)
   ret = FALSE;
 }
 GameThreadRun = 1;
 GameThread = SDL_CreateThread(GameLoop, NULL);

 return(ret);
}
示例#16
0
文件: main.cpp 项目: ben401/OpenEmu
/* Closes a game and frees memory. */
int CloseGame(void)
{
	if(!CurGame) return(0);

	GameThreadRun = 0;

	SDL_WaitThread(GameThread, NULL);

	if(MDFN_GetSettingB("autosave"))
	 MDFNI_SaveState(NULL, "ncq", NULL, NULL);

	MDFNI_CloseGame();

        KillGameInput();
	KillSound();

	CurGame = NULL;

	if(soundrecfn)
         MDFNI_EndWaveRecord();

	return(1);
}
示例#17
0
static void LoadCommonPre(void)
{
 HuC6280_Init();

 // FIXME:  Make these globals less global!
 pce_overclocked = MDFN_GetSettingUI("pce_fast.ocmultiplier");
 PCE_ACEnabled = MDFN_GetSettingB("pce_fast.arcadecard");

 if(pce_overclocked > 1)
  MDFN_printf(_("CPU overclock: %dx\n"), pce_overclocked);

 if(MDFN_GetSettingUI("pce_fast.cdspeed") > 1)
  MDFN_printf(_("CD-ROM speed:  %ux\n"), (unsigned int)MDFN_GetSettingUI("pce_fast.cdspeed"));

 for(int x = 0; x < 0x100; x++)
 {
  HuCPU.PCERead[x] = PCEBusRead;
  HuCPU.PCEWrite[x] = PCENullWrite;
 }

 MDFNMP_Init(1024, (1 << 21) / 1024);

 sbuf = new Blip_Buffer[2];
}
示例#18
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);
}
示例#19
0
static void LoadCommon(void)
{ 
 IsSGX |= MDFN_GetSettingB("pce_fast.forcesgx") ? 1 : 0;

 if(IsHES)
  IsSGX = 1;
 // Don't modify IsSGX past this point.
 
 VDC_Init(IsSGX);
 VDC_SetSettings(MDFN_GetSettingB("pce_fast.nospritelimit"), MDFN_GetSettingB("pce_fast.correct_aspect"));

 if(IsSGX)
 {
  MDFN_printf("SuperGrafx Emulation Enabled.\n");
  HuCPU.PCERead[0xF8] = HuCPU.PCERead[0xF9] = HuCPU.PCERead[0xFA] = HuCPU.PCERead[0xFB] = BaseRAMReadSGX;
  HuCPU.PCEWrite[0xF8] = HuCPU.PCEWrite[0xF9] = HuCPU.PCEWrite[0xFA] = HuCPU.PCEWrite[0xFB] = BaseRAMWriteSGX;

  for(int x = 0xf8; x < 0xfb; x++)
   HuCPU.FastMap[x] = &BaseRAM[(x & 0x3) * 8192];

  HuCPU.PCERead[0xFF] = IOReadSGX;
 }
 else
 {
  HuCPU.PCERead[0xF8] = BaseRAMRead;
  HuCPU.PCERead[0xF9] = HuCPU.PCERead[0xFA] = HuCPU.PCERead[0xFB] = BaseRAMRead_Mirrored;

  HuCPU.PCEWrite[0xF8] = BaseRAMWrite;
  HuCPU.PCEWrite[0xF9] = HuCPU.PCEWrite[0xFA] = HuCPU.PCEWrite[0xFB] = BaseRAMWrite_Mirrored;

  for(int x = 0xf8; x < 0xfb; x++)
   HuCPU.FastMap[x] = &BaseRAM[0];

  HuCPU.PCERead[0xFF] = IORead;
 }

 MDFNMP_AddRAM(IsSGX ? 32768 : 8192, 0xf8 * 8192, BaseRAM);

 HuCPU.PCEWrite[0xFF] = IOWrite;

 psg = new PCEFast_PSG(sbuf);

 psg->SetVolume(1.0);

 if(PCE_IsCD)
 {
  unsigned int cdpsgvolume = MDFN_GetSettingUI("pce_fast.cdpsgvolume");

  if(cdpsgvolume != 100)
  {
   MDFN_printf(_("CD PSG Volume: %d%%\n"), cdpsgvolume);
  }

  psg->SetVolume(0.678 * cdpsgvolume / 100);

 }

 PCEINPUT_Init();

 PCE_Power();

 MDFNGameInfo->LayerNames = IsSGX ? "BG0\0SPR0\0BG1\0SPR1\0" : "Background\0Sprites\0";
 MDFNGameInfo->fps = (uint32)((double)7159090.90909090 / 455 / 263 * 65536 * 256);

 if(!IsHES)
 {
  // Clean this up:
  if(!MDFN_GetSettingB("pce_fast.correct_aspect"))
   MDFNGameInfo->fb_width = 682;

  MDFNGameInfo->nominal_width = MDFN_GetSettingB("pce_fast.correct_aspect") ? 288 : 341;
  MDFNGameInfo->nominal_height = MDFN_GetSettingUI("pce_fast.slend") - MDFN_GetSettingUI("pce_fast.slstart") + 1;

  MDFNGameInfo->lcm_width = MDFN_GetSettingB("pce_fast.correct_aspect") ? 1024 : 341;
  MDFNGameInfo->lcm_height = MDFNGameInfo->nominal_height;
 }
}
示例#20
0
static int LoadCommon(MDFNFILE *fp)
{
 int32 size = fp->size;
 const uint8 *data_ptr = fp->data;

 if(size & 512)
 {
  size -= 512;
  data_ptr += 512;
 }

 /* Assign default settings (US NTSC machine) */
 sms.display     = DISPLAY_NTSC;

 sms.territory   = MDFN_GetSettingI("sms.territory");
 sms.use_fm      = FALSE;


 if(!SMS_CartInit(data_ptr, size))
  return(0);

 if(IS_SMS && sms.territory == TERRITORY_DOMESTIC)
  sms.use_fm = MDFN_GetSettingB("sms.fm");

 MDFNMP_Init(1024, 65536 / 1024);

 system_assign_device(PORT_A, DEVICE_PAD2B);
 system_assign_device(PORT_B, DEVICE_PAD2B);

 MDFNMP_AddRAM(8192, 0xC000, sms.wram);

 sms_init();
 pio_init();
 vdp_init(IS_SMS && sms.territory == TERRITORY_DOMESTIC);
 render_init();

 MDFNGameInfo->GameSetMD5Valid = FALSE;

 uint32 sndclk;

 if(sms.display == DISPLAY_PAL)
 {
  sndclk = 3546893;
  MDFNGameInfo->fps = (uint32)((uint64)65536 * 256 * sndclk / 313 / 228); //6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198
 }
 else
 {
  sndclk = 3579545;
  MDFNGameInfo->fps = (uint32)((uint64)65536 * 256 * sndclk / 262 / 228); //6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198
 }

 MDFNGameInfo->MasterClock = MDFN_MASTERCLOCK_FIXED(sndclk);

 SMS_SoundInit(sndclk, sms.use_fm);

 sms.save = 0;


 system_reset();

 return(1);
}
示例#21
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);
}
示例#22
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);
}
示例#23
0
static int Load(const char *name, MDFNFILE *fp)
{
 uint32 real_rom_size;

 if(fp->size < 65536)
 {
  MDFN_PrintError(_("%s ROM image is too small."), MDFNGameInfo->fullname);
  return(0);
 }

 if(!memcmp(fp->data + fp->size - 0x20, "WSRF", 4))
 {
  const uint8 *wsr_footer = fp->data + fp->size - 0x20;

  IsWSR = TRUE;
  WSRCurrentSong = wsr_footer[0x5];

  Player_Init(256, "", "", "");
 }
 else
  IsWSR = false;

 real_rom_size = (fp->size + 0xFFFF) & ~0xFFFF;
 rom_size = round_up_pow2(real_rom_size); //fp->size);

 wsCartROM = (uint8 *)calloc(1, rom_size);


 // This real_rom_size vs rom_size funny business is intended primarily for handling
 // WSR files.
 if(real_rom_size < rom_size)
  memset(wsCartROM, 0xFF, rom_size - real_rom_size);

 memcpy(wsCartROM + (rom_size - real_rom_size), fp->data, fp->size);

 MDFN_printf(_("ROM:       %dKiB\n"), real_rom_size / 1024);
 md5_context md5;
 md5.starts();
 md5.update(wsCartROM, rom_size);
 md5.finish(MDFNGameInfo->MD5);
 MDFN_printf(_("ROM MD5:   0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());

 uint8 header[10];
 memcpy(header, wsCartROM + rom_size - 10, 10);

 {
  const char *developer_name = "???";
  for(unsigned int x = 0; x < sizeof(Developers) / sizeof(DLEntry); x++)
  {
   if(Developers[x].id == header[0])
   {
    developer_name = Developers[x].name;
    break;
   }
  }
  MDFN_printf(_("Developer: %s (0x%02x)\n"), developer_name, header[0]);
 }

 uint32 SRAMSize = 0;
 eeprom_size = 0;

 switch(header[5])
 {
  case 0x01: SRAMSize = 8*1024; break;
  case 0x02: SRAMSize = 32*1024; break;
  case 0x03: SRAMSize = 16 * 65536; break;
  case 0x04: SRAMSize = 32 * 65536; break; // Dicing Knight!

  case 0x10: eeprom_size = 128; break;
  case 0x20: eeprom_size = 2*1024; break;
  case 0x50: eeprom_size = 1024; break;
 }

 //printf("%02x\n", header[5]);

 if(eeprom_size)
  MDFN_printf(_("EEPROM:  %d bytes\n"), eeprom_size);

 if(SRAMSize)
  MDFN_printf(_("Battery-backed RAM:  %d bytes\n"), SRAMSize);

 MDFN_printf(_("Recorded Checksum:  0x%04x\n"), header[8] | (header[9] << 8));
 {
  uint16 real_crc = 0;
  for(unsigned int i = 0; i < rom_size - 2; i++)
   real_crc += wsCartROM[i];
  MDFN_printf(_("Real Checksum:      0x%04x\n"), real_crc);
 }

 if((header[8] | (header[9] << 8)) == 0x8de1 && (header[0]==0x01)&&(header[2]==0x27)) /* Detective Conan */
 {
  //puts("HAX");
  /* WS cpu is using cache/pipeline or there's protected ROM bank where pointing CS */
  wsCartROM[0xfffe8]=0xea;
  wsCartROM[0xfffe9]=0x00;
  wsCartROM[0xfffea]=0x00;
  wsCartROM[0xfffeb]=0x00;
  wsCartROM[0xfffec]=0x20;
 }

 if(!IsWSR)
 {
  if(header[6] & 0x1)
   MDFNGameInfo->rotated = MDFN_ROTATE90;
 }

 MDFNMP_Init(16384, (1 << 20) / 1024);

 #ifdef WANT_DEBUGGER
 WSwanDBG_Init();
 #endif

 v30mz_init(WSwan_readmem20, WSwan_writemem20, WSwan_readport, WSwan_writeport);
 WSwan_MemoryInit(MDFN_GetSettingB("wswan.language"), wsc, SRAMSize, IsWSR); // EEPROM and SRAM are loaded in this func.
 WSwan_GfxInit();
 MDFNGameInfo->fps = (uint32)((uint64)3072000 * 65536 * 256 / (159*256));
 MDFNGameInfo->GameSetMD5Valid = FALSE;

 WSwan_SoundInit();

 wsMakeTiles();

 Reset();

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

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

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

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

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

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

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

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

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

		return 1;
	}
示例#25
0
static int LoadCommon(void)
{ 
 IsSGX |= MDFN_GetSettingB("pce_fast.forcesgx") ? 1 : 0;

 if(IsHES)
  IsSGX = 1;
 // Don't modify IsSGX past this point.
 
 VDC_Init(IsSGX);

 if(IsSGX)
 {
  MDFN_printf("SuperGrafx Emulation Enabled.\n");
  PCERead[0xF8] = PCERead[0xF9] = PCERead[0xFA] = PCERead[0xFB] = BaseRAMReadSGX;
  PCEWrite[0xF8] = PCEWrite[0xF9] = PCEWrite[0xFA] = PCEWrite[0xFB] = BaseRAMWriteSGX;

  for(int x = 0xf8; x < 0xfb; x++)
   HuCPUFastMap[x] = BaseRAM - 0xf8 * 8192;

  PCERead[0xFF] = IOReadSGX;
 }
 else
 {
  PCERead[0xF8] = BaseRAMRead;
  PCERead[0xF9] = PCERead[0xFA] = PCERead[0xFB] = BaseRAMRead_Mirrored;

  PCEWrite[0xF8] = BaseRAMWrite;
  PCEWrite[0xF9] = PCEWrite[0xFA] = PCEWrite[0xFB] = BaseRAMWrite_Mirrored;

  for(int x = 0xf8; x < 0xfb; x++)
   HuCPUFastMap[x] = BaseRAM - x * 8192;

  PCERead[0xFF] = IORead;
 }

 MDFNMP_AddRAM(IsSGX ? 32768 : 8192, 0xf8 * 8192, BaseRAM);

 PCEWrite[0xFF] = IOWrite;

 HuC6280_Init();

 psg = new PCE_PSG(&sbuf[0], &sbuf[1], PCE_PSG::REVISION_ENHANCED);	//HUC6280A);
 //psg->init(&sbuf[0], &sbuf[1], PCE_PSG::REVISION_ENHANCED);

 psg->SetVolume(1.0);

 if(PCE_IsCD)
 {
  unsigned int cdpsgvolume = MDFN_GetSettingUI("pce_fast.cdpsgvolume");

  if(cdpsgvolume != 100)
  {
   MDFN_printf(_("CD PSG Volume: %d%%\n"), cdpsgvolume);
  }

  psg->SetVolume(0.678 * cdpsgvolume / 100);

 }

 PCEINPUT_Init();

 PCE_Power();

 MDFNGameInfo->LayerNames = IsSGX ? "BG0\0SPR0\0BG1\0SPR1\0" : "Background\0Sprites\0";
 MDFNGameInfo->fps = (uint32)((double)7159090.90909090 / 455 / 263 * 65536 * 256);

 // Clean this up:
 if(!MDFN_GetSettingB("pce_fast.correct_aspect"))
  MDFNGameInfo->fb_width = 682;

 if(!IsHES)
 {
  MDFNGameInfo->nominal_width = MDFN_GetSettingB("pce_fast.correct_aspect") ? 320 : 341;
  MDFNGameInfo->nominal_height = MDFN_GetSettingUI("pce_fast.slend") - MDFN_GetSettingUI("pce_fast.slstart") + 1;

  MDFNGameInfo->lcm_width = MDFN_GetSettingB("pce_fast.correct_aspect") ? 1024 : 341;
  MDFNGameInfo->lcm_height = MDFNGameInfo->nominal_height;
 }

 return(1);
}
示例#26
0
static INLINE bool MDFN_DumpToFileReal(const char *filename, int compress, const std::vector<PtrLengthPair> &pearpairs)
{
 if(MDFN_GetSettingB("filesys.disablesavegz"))
  compress = 0;

 if(compress)
 {
  char mode[64];
  gzFile gp;

  trio_snprintf(mode, 64, "wb%d", compress);

  gp = gzopen(filename, mode);

  if(!gp)
  {
   ErrnoHolder ene(errno);

   MDFN_PrintError(_("Error opening \"%s\": %s"), filename, ene.StrError());
   return(0);
  }

  for(unsigned int i = 0; i < pearpairs.size(); i++)
  {
   const void *data = pearpairs[i].GetData();
   const int64 length = pearpairs[i].GetLength();

   if(gzwrite(gp, data, length) != length)
   {
    int errnum;

    MDFN_PrintError(_("Error writing to \"%s\": %s"), filename, gzerror(gp, &errnum));
    gzclose(gp);
    return(0);
   }
  }

  if(gzclose(gp) != Z_OK) // FIXME: Huhm, how should we handle this?
  {
   MDFN_PrintError(_("Error closing \"%s\""), filename);
   return(0);
  }
 }
 else
 {
  FILE *fp = fopen(filename, "wb");
  if(!fp)
  {
   ErrnoHolder ene(errno);

   MDFN_PrintError(_("Error opening \"%s\": %s"), filename, ene.StrError());
   return(0);
  }

  for(unsigned int i = 0; i < pearpairs.size(); i++)
  {
   const void *data = pearpairs[i].GetData();
   const uint64 length = pearpairs[i].GetLength();

   if(fwrite(data, 1, length, fp) != length)
   {
    ErrnoHolder ene(errno);

    MDFN_PrintError(_("Error writing to \"%s\": %s"), filename, ene.StrError());
    fclose(fp);
    return(0);
   }
  }

  if(fclose(fp) == EOF)
  {
   ErrnoHolder ene(errno);

   MDFN_PrintError(_("Error closing \"%s\": %s"), filename, ene.StrError());
   return(0);
  }
 }
 return(1);
}
示例#27
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Settings::getBool(const string& key) const
{
  return MDFN_GetSettingB((std::string("stella.") + key).c_str());
}
示例#28
0
static MDFN_COLD void Load(GameFile* gf)
{
 try
 {
	LoadFunction_t LoadFunction = NULL;

	LoadFunction = GetLoadFunctionByMagic(gf);

	// If the file type isn't recognized, return -1!
	if(!LoadFunction)
	 throw MDFN_Error(0, _("File format is unknown to module \"%s\"."), MDFNGameInfo->shortname);

	InitCommon(gf->fbase);

	LoadFunction(gf->stream, &GameInterface);

	{
	 int w;

	 if(MDFNGameInfo->VideoSystem == VIDSYS_NTSC)
	  w = 0;
	 else if(MDFNGameInfo->VideoSystem == VIDSYS_PAL)
	  w = 1;
	 else
	 {
	  w = MDFN_GetSettingB("nes.pal");
	  MDFNGameInfo->VideoSystem = w ? VIDSYS_PAL : VIDSYS_NTSC;
	 }
	 PAL=w?1:0;
	 MDFNGameInfo->fps = PAL? 838977920 : 1008307711;
	 MDFNGameInfo->MasterClock = MDFN_MASTERCLOCK_FIXED(PAL ? PAL_CPU : NTSC_CPU);
	}

	X6502_Init();
	MDFNPPU_Init();
        MDFNSND_Init(PAL);
	NESINPUT_Init();

	if(NESIsVSUni)
	 MDFN_VSUniInstallRWHooks();

	if(MDFNGameInfo->GameType != GMT_PLAYER)
         if(MDFN_GetSettingB("nes.gg"))
	  Genie_Init();

        PowerNES();

        MDFN_InitPalette(NESIsVSUni ? MDFN_VSUniGetPaletteNum() : (bool)PAL, NULL, 0);

	if(MDFNGameInfo->GameType != GMT_PLAYER)
	 MDFNGameInfo->CPInfoActiveBF = 1 << (NESIsVSUni ? MDFN_VSUniGetPaletteNum() : (bool)PAL);
	else
	 MDFNGameInfo->CPInfoActiveBF = 0;

 }
 catch(...)
 {
  Cleanup();
  throw;
 }
}
示例#29
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);
}