Beispiel #1
0
void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
{
#ifdef __linux__
	// Important Linux note: When the title is set in fullscreen the window is redrawn. Unfortunately
	// an intermediate white screen appears too which leads to a very annoying flickering.
	if (IsFullScreen()) return;
#endif
	AppConfig::UiTemplateOptions& templates = g_Conf->Templates;

	double fps = wxGetApp().FpsManager.GetFramerate();
	// The "not PAL" case covers both Region_NTSC and Region_NTSC_PROGRESSIVE
	float per = gsRegionMode == Region_PAL ? (fps * 100) / EmuConfig.GS.FrameratePAL.ToFloat() : (fps * 100) / EmuConfig.GS.FramerateNTSC.ToFloat();

	char gsDest[128];
	gsDest[0] = 0; // No need to set whole array to NULL.
	GSgetTitleInfo2( gsDest, sizeof(gsDest) );

	wxString limiterStr = templates.LimiterUnlimited;

	if( g_Conf->EmuOptions.GS.FrameLimitEnable )
	{
		switch( g_LimiterMode )
		{
			case Limit_Nominal:	limiterStr = templates.LimiterNormal; break;
			case Limit_Turbo:	limiterStr = templates.LimiterTurbo; break;
			case Limit_Slomo:	limiterStr = templates.LimiterSlowmo; break;
		}
	}

	FastFormatUnicode cpuUsage;
	if (m_CpuUsage.IsImplemented()) {
		m_CpuUsage.UpdateStats();

		cpuUsage.Write(L"EE: %3d%%", m_CpuUsage.GetEEcorePct());
		cpuUsage.Write(L" | GS: %3d%%", m_CpuUsage.GetGsPct());

		if (THREAD_VU1)
			cpuUsage.Write(L" | VU: %3d%%", m_CpuUsage.GetVUPct());

		pxNonReleaseCode(cpuUsage.Write(L" | UI: %3d%%", m_CpuUsage.GetGuiPct()));
	}

	const u64& smode2 = *(u64*)PS2GS_BASE(GS_SMODE2);
	wxString omodef = (smode2 & 2) ? templates.OutputFrame : templates.OutputField;
	wxString omodei = (smode2 & 1) ? templates.OutputInterlaced : templates.OutputProgressive;

	wxString title = templates.TitleTemplate;
	title.Replace(L"${slot}",		pxsFmt(L"%d", States_GetCurrentSlot()));
	title.Replace(L"${limiter}",	limiterStr);
	title.Replace(L"${speed}",		pxsFmt(L"%3d%%", lround(per)));
	title.Replace(L"${vfps}",		pxsFmt(L"%.02f", fps));
	title.Replace(L"${cpuusage}",	cpuUsage);
	title.Replace(L"${omodef}",		omodef);
	title.Replace(L"${omodei}",		omodei);
	title.Replace(L"${gsdx}",		fromUTF8(gsDest));
	if (CoreThread.IsPaused())
		title = templates.Paused + title;

	SetTitle(title);
}
Beispiel #2
0
// returns FALSE if the mprotect call fails with an ENOMEM.
// Raises assertions on other types of POSIX errors (since those typically reflect invalid object
// or memory states).
static bool _memprotect( void* baseaddr, size_t size, const PageProtectionMode& mode )
{
	PageSizeAssertionTest(size);

	uint lnxmode = 0;

	if (mode.CanWrite())	lnxmode |= PROT_WRITE;
	if (mode.CanRead())		lnxmode |= PROT_READ;
	if (mode.CanExecute())	lnxmode |= PROT_EXEC | PROT_READ;

	const int result = mprotect( baseaddr, size, lnxmode );

	if (result == 0) return true;

	switch(errno)
	{
		case EINVAL:
			pxFailDev(pxsFmt(L"mprotect returned EINVAL @ 0x%08X -> 0x%08X  (mode=%s)",
				baseaddr, (uptr)baseaddr+size, mode.ToString().c_str())
			);
		break;

		case EACCES:
			pxFailDev(pxsFmt(L"mprotect returned EACCES @ 0x%08X -> 0x%08X  (mode=%s)",
				baseaddr, (uptr)baseaddr+size, mode.ToString().c_str())
			);
		break;

		case ENOMEM:
			// caller handles assertion or exception, or whatever.
		break;
	}
	return false;
}
Beispiel #3
0
Exception::RuntimeError::RuntimeError( const std::exception& ex, const wxString& prefix )
{
	IsSilent = false;

	SetDiagMsg( pxsFmt( L"STL Exception%s: %s",
		(prefix.IsEmpty() ? L"" : pxsFmt(L" (%s)", WX_STR(prefix)).c_str()),
		WX_STR(fromUTF8( ex.what() ))
	) );
}
Beispiel #4
0
void mVUreserveCache(microVU& mVU) {

	mVU.cache_reserve = new RecompiledCodeReserve(pxsFmt("Micro VU%u Recompiler Cache", mVU.index));
	mVU.cache_reserve->SetProfilerName(pxsFmt("mVU%urec", mVU.index));
	
	mVU.cache = mVU.index ?
		(u8*)mVU.cache_reserve->Reserve(mVU.cacheSize * _1mb, HostMemoryMap::mVU1rec):
		(u8*)mVU.cache_reserve->Reserve(mVU.cacheSize * _1mb, HostMemoryMap::mVU0rec);

	mVU.cache_reserve->ThrowIfNotOk();
}
void isoFile::outWrite( const void* src, size_t size )
{
	m_outstream->Write(src, size);
	if(m_outstream->GetLastError() == wxSTREAM_WRITE_ERROR)
	{
		int err = errno;
		if (!err)
			throw Exception::BadStream(m_filename).SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file", size));

		ScopedExcept ex(Exception::FromErrno(m_filename, err));
		ex->SetDiagMsg( pxsFmt(L"An error occurred while writing %u bytes to file: %s", size, ex->DiagMsg().c_str()) );
		ex->Rethrow();
	}
}
Beispiel #6
0
static __ri void PageSizeAssertionTest( size_t size )
{
	pxAssertMsg( (__pagesize == getpagesize()), pxsFmt(
		"Internal system error: Operating system pagesize does not match compiled pagesize.\n\t"
		L"\tOS Page Size: 0x%x (%d), Compiled Page Size: 0x%x (%u)",
		getpagesize(), getpagesize(), __pagesize, __pagesize )
	);

	pxAssertDev( (size & (__pagesize-1)) == 0, pxsFmt(
		L"Memory block size must be a multiple of the target platform's page size.\n"
		L"\tPage Size: 0x%x (%u), Block Size: 0x%x (%u)",
		__pagesize, __pagesize, size, size )
	);
}
Beispiel #7
0
// Translates an Errno code into an exception.
// Throws an exception based on the given error code (usually taken from ANSI C's errno)
BaseException* Exception::FromErrno( const wxString& streamname, int errcode )
{
	pxAssumeDev( errcode != 0, "Invalid NULL error code?  (errno)" );

	switch( errcode )
	{
		case EINVAL:
			pxFailDev( L"Invalid argument" );
			return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Invalid argument? (likely caused by an unforgivable programmer error!)" );

		case EACCES:	// Access denied!
			return new Exception::AccessDenied( streamname );

		case EMFILE:	// Too many open files!
			return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"Too many open files");	// File handle allocation failure

		case EEXIST:
			return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"File already exists");

		case ENOENT:	// File not found!
			return new Exception::FileNotFound( streamname );

		case EPIPE:
			return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Broken pipe");

		case EBADF:
			return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Bad file number");

		default:
			return &(new Exception::BadStream( streamname ))->SetDiagMsg(pxsFmt( L"General file/stream error [errno: %d]", errcode ));
	}
}
Beispiel #8
0
// Throws an exception based on the value returned from GetLastError.
// Performs an option return value success/fail check on hresult.
void StreamException_ThrowLastError( const wxString& streamname, HANDLE result )
{
	if( result != INVALID_HANDLE_VALUE ) return;

	int error = GetLastError();

	switch( error )
	{
		case ERROR_FILE_NOT_FOUND:
			throw Exception::FileNotFound( streamname );

		case ERROR_PATH_NOT_FOUND:
			throw Exception::FileNotFound( streamname );

		case ERROR_TOO_MANY_OPEN_FILES:
			throw Exception::CannotCreateStream( streamname ).SetDiagMsg(L"Too many open files");

		case ERROR_ACCESS_DENIED:
			throw Exception::AccessDenied( streamname );

		case ERROR_INVALID_HANDLE:
			throw Exception::BadStream( streamname ).SetDiagMsg(L"Stream object or handle is invalid");

		case ERROR_SHARING_VIOLATION:
			throw Exception::AccessDenied( streamname ).SetDiagMsg(L"Sharing violation");

		default:
		{
			throw Exception::BadStream( streamname ).SetDiagMsg(pxsFmt( L"常规 Win32 文件/流 错误 [GetLastError: %d]", error ));
		}
	}
}
Beispiel #9
0
void RecentIsoManager::AppStatusEvent_OnUiSettingsLoadSave( const AppSettingsEventInfo& evt )
{
	IniInterface& ini( evt.GetIni() );

	if( ini.IsSaving() )
	{
		// Wipe existing recent iso list if we're saving, because our size might have changed
		// and that could leave some residual entries in the config.

		ini.GetConfig().SetRecordDefaults( false );

		ini.GetConfig().DeleteGroup( L"RecentIso" );
		ScopedIniGroup groupie( ini, L"RecentIso" );

		int cnt = m_Items.size();
		for( int i=0; i<cnt; ++i )
		{
			wxFileName item_filename = wxFileName(m_Items[i].Filename);
			ini.Entry( pxsFmt( L"Filename%02d", i ),  item_filename, wxFileName(L""), IsPortable());
		}
		
		ini.GetConfig().SetRecordDefaults( true );
	}
	else
	{
		LoadListFrom(ini);
	}
}
Beispiel #10
0
void pxStream_OpenCheck( const wxStreamBase& stream, const wxString& fname, const wxString& mode )
{
	if (stream.IsOk()) return;

	ScopedExcept ex(Exception::FromErrno(fname, errno));
	ex->SetDiagMsg( pxsFmt(L"Unable to open the file for %s: %s", mode.c_str(), ex->DiagMsg().c_str()) );
	ex->Rethrow();
}
Beispiel #11
0
// This error message is shared by R5900, R3000, and microVU recompilers.  It is not used by the
// SuperVU recompiler, since it has its own customized message.
void RecompiledCodeReserve::ThrowIfNotOk() const
{
	if (IsOk()) return;

	throw Exception::OutOfMemory(m_name)
		.SetDiagMsg(pxsFmt( L"Recompiled code cache could not be mapped." ))
		.SetUserMsg( pxE( L"This recompiler was unable to reserve contiguous memory required for internal caches.  This error can be caused by low virtual memory resources, such as a small or disabled swapfile, or by another program that is hogging a lot of memory."
		));
}
Beispiel #12
0
void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
{
#ifdef __linux__
    // Important Linux note: When the title is set in fullscreen the window is redrawn. Unfortunately
    // an intermediate white screen appears too which leads to a very annoying flickering.
    if (IsFullScreen()) return;
#endif

    double fps = wxGetApp().FpsManager.GetFramerate();

    char gsDest[128];
    GSgetTitleInfo2( gsDest, sizeof(gsDest) );

    const wxChar* limiterStr = L"None";

    if( g_Conf->EmuOptions.GS.FrameLimitEnable )
    {
        switch( g_LimiterMode )
        {
        case Limit_Nominal:
            limiterStr = L"Normal";
            break;
        case Limit_Turbo:
            limiterStr = L"Turbo";
            break;
        case Limit_Slomo:
            limiterStr = L"Slomo";
            break;
        }
    }

    FastFormatUnicode cpuUsage;
    if (m_CpuUsage.IsImplemented()) {
        m_CpuUsage.UpdateStats();
        if (THREAD_VU1) { // Display VU thread's usage
            cpuUsage.Write(L" | EE: %3d%% | GS: %3d%% | VU: %3d%% | UI: %3d%%",
                           m_CpuUsage.GetEEcorePct(),	m_CpuUsage.GetGsPct(),
                           m_CpuUsage.GetVUPct(),		m_CpuUsage.GetGuiPct());
        }
        else {
            cpuUsage.Write(L" | EE: %3d%% | GS: %3d%% | UI: %3d%%",
                           m_CpuUsage.GetEEcorePct(),	m_CpuUsage.GetGsPct(),
                           m_CpuUsage.GetGuiPct());
        }
    }

    const u64& smode2 = *(u64*)PS2GS_BASE(GS_SMODE2);

    SetTitle( pxsFmt( L"%s | %ls (%ls) | Limiter: %ls | fps: %6.02f%ls | State %d",
                      WX_STR(fromUTF8(gsDest)),
                      (smode2 & 1) ? L"Interlaced" : L"Progressive",
                      (smode2 & 2) ? L"frame" : L"field",
                      limiterStr, fps, cpuUsage.c_str(), States_GetCurrentSlot() )
            );

    //States_GetCurrentSlot()
}
Beispiel #13
0
void HostSys::MemProtect( void* baseaddr, size_t size, const PageProtectionMode& mode )
{
	if (!_memprotect(baseaddr, size, mode))
	{
		throw Exception::OutOfMemory( L"MemProtect" )
			.SetDiagMsg(pxsFmt( L"mprotect failed @ 0x%08X -> 0x%08X  (mode=%s)",
				baseaddr, (uptr)baseaddr+size, mode.ToString().c_str()
			)
		);
	}
}
Beispiel #14
0
// This function always returns a valid DiscID -- using the Sony serial when possible, and
// falling back on the CRC checksum of the ELF binary if the PS2 software being run is
// homebrew or some other serial-less item.
wxString SysGetDiscID()
{
	if( !DiscSerial.IsEmpty() ) return DiscSerial;

	if( !ElfCRC )
	{
		// system is currently running the BIOS
		return SysGetBiosDiscID();
	}

	return pxsFmt( L"%08x", ElfCRC );
}
Beispiel #15
0
// ------------------------------------------------------------------------
void AppConfig::LoadSaveMemcards( IniInterface& ini )
{
	ScopedIniGroup path( ini, L"MemoryCards" );

	for( uint slot=0; slot<2; ++slot )
	{
		ini.Entry( pxsFmt( L"Slot%u_Enable", slot+1 ),
			Mcd[slot].Enabled, Mcd[slot].Enabled );
		ini.Entry( pxsFmt( L"Slot%u_Filename", slot+1 ),
			Mcd[slot].Filename, Mcd[slot].Filename );
	}

	for( uint slot=2; slot<8; ++slot )
	{
		int mtport = FileMcd_GetMtapPort(slot)+1;
		int mtslot = FileMcd_GetMtapSlot(slot)+1;

		ini.Entry( pxsFmt( L"Multitap%u_Slot%u_Enable", mtport, mtslot ),
			Mcd[slot].Enabled, Mcd[slot].Enabled );
		ini.Entry( pxsFmt( L"Multitap%u_Slot%u_Filename", mtport, mtslot ),
			Mcd[slot].Filename, Mcd[slot].Filename );
	}
}
Beispiel #16
0
// This function always returns a valid DiscID -- using the Sony serial when possible, and
// falling back on the CRC checksum of the ELF binary if the PS2 software being run is
// homebrew or some other serial-less item.
wxString SysGetDiscID()
{
	if( !DiscSerial.IsEmpty() ) return DiscSerial;
	
	if( !ElfCRC )
	{
		// FIXME: system is currently running the BIOS, so it should return a serial based on
		// the BIOS being run (either a checksum of the BIOS roms, and/or a string based on BIOS
		// region and revision).
		
		return wxEmptyString;
	}

	return pxsFmt( L"%08x", ElfCRC );
}
Beispiel #17
0
void BaseVmReserveListener::OnPageFaultEvent(const PageFaultInfo& info, bool& handled)
{
	sptr offset = (info.addr - (uptr)m_baseptr) / __pagesize;
	if ((offset < 0) || ((uptr)offset >= m_pages_reserved)) return;

	if (!m_allow_writes)
	{
		pxFailRel( pxsFmt(
			L"Memory Protection Fault @ %s (%s)\n"
			L"Modification of this reserve has been disabled (m_allow_writes == false).",
			pxsPtr(info.addr), m_name.c_str())
		);
		return;
	}

	// Linux Note!  the SIGNAL handler is very limited in what it can do, and not only can't
	// we let the C++ exception try to unwind the stack, we may not be able to log it either.
	// (but we might as well try -- kernel/posix rules says not to do it, but Linux kernel
	//  implementations seem to support it).
	// Note also that logging the exception and/or issuing an assertion dialog are always
	// possible if the thread handling the signal is not the main thread.

	// In windows we can let exceptions bubble out of the page fault handler.  SEH will more
	// or less handle them in a semi-expected way, and might even avoid a GPF long enough
	// for the system to log the error or something.

	#ifndef __WXMSW__
	try	{
	#endif
		DoCommitAndProtect( offset );
		handled = true;

	#ifndef __WXMSW__
	}
	catch (Exception::BaseException& ex)
	{
		handled = false;
		if (!wxThread::IsMain())
		{
			pxFailRel( ex.FormatDiagnosticMessage() );
		}
		else
		{
			wxTrap();
		}
	}
	#endif
}
Beispiel #18
0
void HostSys::MmapResetPtr(void* base, size_t size)
{
	// On linux the only way to reset the memory is to unmap and remap it as PROT_NONE.
	// That forces linux to unload all committed pages and start from scratch.

	// FIXME: Ideally this code would have some threading lock on it to prevent any other
	// malloc/free code in the current process from interfering with the operation, but I
	// can't think of any good way to do that.  (generally it shouldn't be a problem in
	// PCSX2 anyway, since MmapReset is only called when the ps2vm is suspended; so that
	// pretty well stops all PCSX2 threads anyway).

	Munmap(base, size);
	void* result = MmapReservePtr(base, size);

	pxAssertRel ((uptr)result == (uptr)base, pxsFmt(
		"Virtual memory decommit failed: memory at 0x%08X -> 0x%08X could not be remapped.  "
		"This is likely caused by multi-thread memory contention.", base, (uptr)base+size
	));
}
Beispiel #19
0
void RecentIsoManager::LoadListFrom( IniInterface& ini )
{
	if (!ini.IsOk()) return;

	ini.GetConfig().SetRecordDefaults( false );

	RemoveAllFromMenu();

	m_MaxLength = g_Conf->RecentIsoCount;
	ScopedIniGroup groupie( ini, L"RecentIso" );
	for( uint i=0; i<m_MaxLength; ++i )
	{
		wxFileName loadtmp(L"");
		ini.Entry( pxsFmt( L"Filename%02d", i ), loadtmp, loadtmp, true );
		if( loadtmp.GetFullName()!=L"" ) Add( loadtmp.GetFullPath() );
	}
	Add( g_Conf->CurrentIso );

	ini.GetConfig().SetRecordDefaults( true );
}
Beispiel #20
0
void BaseVmReserveListener::CommitBlocks( uptr page, uint blocks )
{
	const uptr blocksbytes = blocks * m_blocksize * __pagesize;
	void* blockptr = (u8*)m_baseptr + (page * __pagesize);

	// Depending on the operating system, this call could fail if the system is low on either
	// physical ram or virtual memory.
	if (!HostSys::MmapCommitPtr(blockptr, blocksbytes, m_prot_mode))
	{
		throw Exception::OutOfMemory(m_name)
			.SetDiagMsg(pxsFmt("An additional %u blocks @ 0x%08x were requested, but could not be committed!", blocks, blockptr));
	}

	u8* init = (u8*)blockptr;
	u8* endpos = init + blocksbytes;
	for( ; init<endpos; init += m_blocksize*__pagesize )
		OnCommittedBlock(init);

	m_pages_commited += m_blocksize * blocks;
}
Beispiel #21
0
// Linux implementation of SIGSEGV handler.  Bind it using sigaction().
static void SysPageFaultSignalFilter( int signal, siginfo_t *siginfo, void * )
{
	// [TODO] : Add a thread ID filter to the Linux Signal handler here.
	// Rationale: On windows, the __try/__except model allows per-thread specific behavior
	// for page fault handling.  On linux, there is a single signal handler for the whole
	// process, but the handler is executed by the thread that caused the exception.


	// Stdio Usage note: SIGSEGV handling is a synchronous in-thread signal.  It is done
	// from the context of the current thread and stackframe.  So long as the thread is not
	// the main/ui thread, use of the px assertion system should be safe.  Use of stdio should
	// be safe even on the main thread.
	//  (in other words, stdio limitations only really apply to process-level asynchronous
	//   signals)

	// Note: Use of stdio functions isn't safe here.  Avoid console logs,
	// assertions, file logs, or just about anything else useful.


	// Note: This signal can be accessed by the EE or MTVU thread
	// Source_PageFault is a global variable with its own state information
	// so for now we lock this exception code unless someone can fix this better...
	Threading::ScopedLock lock(PageFault_Mutex);

	Source_PageFault->Dispatch( PageFaultInfo( (uptr)siginfo->si_addr & ~m_pagemask ) );

	// resumes execution right where we left off (re-executes instruction that
	// caused the SIGSEGV).
	if (Source_PageFault->WasHandled()) return;

	if (!wxThread::IsMain())
	{
		pxFailRel(pxsFmt("Unhandled page fault @ 0x%08x", siginfo->si_addr));
	}

	// Bad mojo!  Completely invalid address.
	// Instigate a trap if we're in a debugger, and if not then do a SIGKILL.

	wxTrap();
	if (!IsDebugBuild) raise( SIGKILL );
}
Beispiel #22
0
		cpuUsage.Write(L"EE: %3d%%", m_CpuUsage.GetEEcorePct());
		cpuUsage.Write(L" | GS: %3d%%", m_CpuUsage.GetGsPct());

		if (THREAD_VU1)
			cpuUsage.Write(L" | VU: %3d%%", m_CpuUsage.GetVUPct());

		pxNonReleaseCode(cpuUsage.Write(L" | UI: %3d%%", m_CpuUsage.GetEEcorePct());)
	}

	const u64& smode2 = *(u64*)PS2GS_BASE(GS_SMODE2);
	wxString omodef = (smode2 & 2) ? templates.OutputFrame : templates.OutputField;
	wxString omodei = (smode2 & 1) ? templates.OutputInterlaced : templates.OutputProgressive;

	wxString title = templates.TitleTemplate;
	title.Replace(L"${slot}",		pxsFmt(L"%d", States_GetCurrentSlot()));
	title.Replace(L"${limiter}",	limiterStr);
	title.Replace(L"${speed}",		pxsFmt(L"%3d%%", lround(per)));
	title.Replace(L"${vfps}",		pxsFmt(L"%.02f", fps));
	title.Replace(L"${cpuusage}",	cpuUsage);
	title.Replace(L"${omodef}",		omodef);
	title.Replace(L"${omodei}",		omodei);
	title.Replace(L"${gsdx}",		fromUTF8(gsDest));

	SetTitle(title);
}

void GSFrame::OnActivate( wxActivateEvent& evt )
{
	if( IsBeingDeleted() ) return;
Beispiel #23
0
void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
{
	// Update the title only after the completion of at least a single Vsync, it's pointless to display the fps
	// when there are have been no frames rendered and SMODE2 register seems to fresh start with 0 on all the bitfields which
	// leads to the value of INT bit as 0 initially and the games are mentioned as progressive which is a bit misleading,
	// to prevent such issues, let's update the title after the actual frame rendering starts.
	if (g_FrameCount == 0)
		return;

	double fps = wxGetApp().FpsManager.GetFramerate();

	FastFormatUnicode cpuUsage;
	if (m_CpuUsage.IsImplemented()) {
		m_CpuUsage.UpdateStats();

		if (!IsFullScreen()) {
			cpuUsage.Write(L"EE: %3d%%", m_CpuUsage.GetEEcorePct());
			cpuUsage.Write(L" | GS: %3d%%", m_CpuUsage.GetGsPct());

			if (THREAD_VU1)
				cpuUsage.Write(L" | VU: %3d%%", m_CpuUsage.GetVUPct());

			pxNonReleaseCode(cpuUsage.Write(L" | UI: %3d%%", m_CpuUsage.GetGuiPct()));
		}

		if (THREAD_VU1)
			OSDmonitor(Color_StrongGreen, "VU:", std::to_string(m_CpuUsage.GetVUPct()).c_str());

		OSDmonitor(Color_StrongGreen, "EE:", std::to_string(m_CpuUsage.GetEEcorePct()).c_str());
		OSDmonitor(Color_StrongGreen, "GS:", std::to_string(m_CpuUsage.GetGsPct()).c_str());
		pxNonReleaseCode(OSDmonitor(Color_StrongGreen, "UI:", std::to_string(m_CpuUsage.GetGuiPct()).c_str()));
	}

	std::ostringstream out;
	out << std::fixed << std::setprecision(2) << fps;
	OSDmonitor(Color_StrongGreen, "FPS:", out.str());

#ifdef __linux__
	// Important Linux note: When the title is set in fullscreen the window is redrawn. Unfortunately
	// an intermediate white screen appears too which leads to a very annoying flickering.
	if (IsFullScreen()) return;
#endif

	AppConfig::UiTemplateOptions& templates = g_Conf->Templates;

	float percentage = (fps * 100) / GetVerticalFrequency().ToFloat();

	char gsDest[128];
	gsDest[0] = 0; // No need to set whole array to NULL.
	GSgetTitleInfo2( gsDest, sizeof(gsDest) );

	wxString limiterStr = templates.LimiterUnlimited;

	if( g_Conf->EmuOptions.GS.FrameLimitEnable )
	{
		switch( g_LimiterMode )
		{
			case Limit_Nominal:	limiterStr = templates.LimiterNormal; break;
			case Limit_Turbo:	limiterStr = templates.LimiterTurbo; break;
			case Limit_Slomo:	limiterStr = templates.LimiterSlowmo; break;
		}
	}

	const u64& smode2 = *(u64*)PS2GS_BASE(GS_SMODE2);
	wxString omodef = (smode2 & 2) ? templates.OutputFrame : templates.OutputField;
	wxString omodei = (smode2 & 1) ? templates.OutputInterlaced : templates.OutputProgressive;

	wxString title = templates.TitleTemplate;
	title.Replace(L"${slot}",		pxsFmt(L"%d", States_GetCurrentSlot()));
	title.Replace(L"${limiter}",	limiterStr);
	title.Replace(L"${speed}",		pxsFmt(L"%3d%%", lround(percentage)));
	title.Replace(L"${vfps}",		pxsFmt(L"%.02f", fps));
	title.Replace(L"${cpuusage}",	cpuUsage);
	title.Replace(L"${omodef}",		omodef);
	title.Replace(L"${omodei}",		omodei);
	title.Replace(L"${gsdx}",		fromUTF8(gsDest));
	title.Replace(L"${videomode}",	ReportVideoMode());
	if (CoreThread.IsPaused())
		title = templates.Paused + title;

	SetTitle(title);
}
Beispiel #24
0
static __fi void mVUthrowHardwareDeficiency(const wxChar* extFail, int vuIndex) {
	throw Exception::HardwareDeficiency()
		.SetDiagMsg(pxsFmt(L"microVU%d recompiler init failed: %s is not available.", vuIndex, extFail))
		.SetUserMsg(pxsFmt(_("%s Extensions not found.  microVU requires a host CPU with SSE2 extensions."), extFail));
}
Beispiel #25
0
wxString u128::ToString64() const
{
	return pxsFmt( L"0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3] );
}
Beispiel #26
0
		cpuUsage.Write(L" | EE: %3d%%", m_CpuUsage.GetEEcorePct());
		cpuUsage.Write(L" | GS: %3d%%", m_CpuUsage.GetGsPct());

		if (THREAD_VU1)
			cpuUsage.Write(L" | VU: %3d%%", m_CpuUsage.GetVUPct());

		pxNonReleaseCode(cpuUsage.Write(L" | UI: %3d%%", m_CpuUsage.GetEEcorePct());)
	}

	const u64& smode2 = *(u64*)PS2GS_BASE(GS_SMODE2);

	SetTitle( pxsFmt( L"Slot %d | Speed%ls: %3d%% (%.02f)%ls | %ls-%ls | %s",
		States_GetCurrentSlot(),
		limiterStr, lround(per), fps,
		cpuUsage.c_str(),
		(smode2 & 2) ? L"frame" : L"field",
		(smode2 & 1) ? L"i" : L"p",
		WX_STR(fromUTF8(gsDest)))
	);
}

void GSFrame::OnActivate( wxActivateEvent& evt )
{
	if( IsBeingDeleted() ) return;

	evt.Skip();
	if( wxWindow* gsPanel = GetViewport() ) gsPanel->SetFocus();
}

void GSFrame::OnMove( wxMoveEvent& evt )
Beispiel #27
0
void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
{
	double fps = wxGetApp().FpsManager.GetFramerate();

	FastFormatUnicode cpuUsage;
	if (m_CpuUsage.IsImplemented()) {
		m_CpuUsage.UpdateStats();

		if (!IsFullScreen()) {
			cpuUsage.Write(L"EE: %3d%%", m_CpuUsage.GetEEcorePct());
			cpuUsage.Write(L" | GS: %3d%%", m_CpuUsage.GetGsPct());

			if (THREAD_VU1)
				cpuUsage.Write(L" | VU: %3d%%", m_CpuUsage.GetVUPct());

			pxNonReleaseCode(cpuUsage.Write(L" | UI: %3d%%", m_CpuUsage.GetGuiPct()));
		}

		if (THREAD_VU1)
			OSDmonitor(Color_StrongGreen, "VU:", std::to_string(m_CpuUsage.GetVUPct()).c_str());

		OSDmonitor(Color_StrongGreen, "EE:", std::to_string(m_CpuUsage.GetEEcorePct()).c_str());
		OSDmonitor(Color_StrongGreen, "GS:", std::to_string(m_CpuUsage.GetGsPct()).c_str());
		pxNonReleaseCode(OSDmonitor(Color_StrongGreen, "UI:", std::to_string(m_CpuUsage.GetGuiPct()).c_str()));
	}

	std::ostringstream out;
	out << std::fixed << std::setprecision(2) << fps;
	OSDmonitor(Color_StrongGreen, "FPS:", out.str());

	// Important Linux note: When the title is set in fullscreen the window is redrawn. Unfortunately
	// an intermediate white screen appears too which leads to a very annoying flickering.
	if (IsFullScreen()) return;

	AppConfig::UiTemplateOptions& templates = g_Conf->Templates;

	float percentage = (fps * 100) / GetVerticalFrequency().ToFloat();

	char gsDest[128];
	gsDest[0] = 0; // No need to set whole array to NULL.
	GSgetTitleInfo2( gsDest, sizeof(gsDest) );

	wxString limiterStr = templates.LimiterUnlimited;

	if( g_Conf->EmuOptions.GS.FrameLimitEnable )
	{
		switch( g_LimiterMode )
		{
			case Limit_Nominal:	limiterStr = templates.LimiterNormal; break;
			case Limit_Turbo:	limiterStr = templates.LimiterTurbo; break;
			case Limit_Slomo:	limiterStr = templates.LimiterSlowmo; break;
		}
	}

	const u64& smode2 = *(u64*)PS2GS_BASE(GS_SMODE2);
	wxString omodef = (smode2 & 2) ? templates.OutputFrame : templates.OutputField;
	wxString omodei = (smode2 & 1) ? templates.OutputInterlaced : templates.OutputProgressive;

	wxString title = templates.TitleTemplate;
	title.Replace(L"${slot}",		pxsFmt(L"%d", States_GetCurrentSlot()));
	title.Replace(L"${limiter}",	limiterStr);
	title.Replace(L"${speed}",		pxsFmt(L"%3d%%", lround(percentage)));
	title.Replace(L"${vfps}",		pxsFmt(L"%.02f", fps));
	title.Replace(L"${cpuusage}",	cpuUsage);
	title.Replace(L"${omodef}",		omodef);
	title.Replace(L"${omodei}",		omodei);
	title.Replace(L"${gsdx}",		fromUTF8(gsDest));
	if (CoreThread.IsPaused())
		title = templates.Paused + title;

	SetTitle(title);
}