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); }
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); }
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; }
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); }
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; } }
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 }
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 }
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; } }
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); }
// 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)); }
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); }
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 }
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); }
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); }
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); }
/* 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); }
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]; }
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); }
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; } }
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); }
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); }
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); }
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); }
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; }
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); }
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); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Settings::getBool(const string& key) const { return MDFN_GetSettingB((std::string("stella.") + key).c_str()); }
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; } }
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); }