Пример #1
0
EmuScreen::EmuScreen(const std::string &filename) : invalid_(true) {
	CheckGLExtensions();
	std::string fileToStart = filename;
	// This is probably where we should start up the emulated PSP.
	INFO_LOG(BOOT, "Starting up hardware.");

	CoreParameter coreParam;
	coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER;
	coreParam.gpuCore = GPU_GLES;
	coreParam.enableSound = g_Config.bEnableSound;
	coreParam.fileToStart = fileToStart;
	coreParam.mountIso = "";
	coreParam.startPaused = false;
	coreParam.enableDebugging = false;
	coreParam.printfEmuLog = false;
	coreParam.headLess = false;
#ifndef _WIN32
	if (g_Config.iWindowZoom < 1 || g_Config.iWindowZoom > 2)
		g_Config.iWindowZoom = 1;
#endif
	coreParam.renderWidth = 480 * g_Config.iWindowZoom;
	coreParam.renderHeight = 272 * g_Config.iWindowZoom;
	coreParam.outputWidth = dp_xres;
	coreParam.outputHeight = dp_yres;
	coreParam.pixelWidth = pixel_xres;
	coreParam.pixelHeight = pixel_yres;
	coreParam.useMediaEngine = false;
	if (g_Config.SSAntiAliasing) {
		coreParam.renderWidth *= 2;
		coreParam.renderHeight *= 2;
	}
	std::string error_string;
	if (PSP_Init(coreParam, &error_string)) {
		invalid_ = false;
	} else {
		invalid_ = true;
		errorMessage_ = error_string;
		ERROR_LOG(BOOT, "%s", errorMessage_.c_str());
		return;
	}

	globalUIState = UISTATE_INGAME;
	host->BootDone();
	host->UpdateDisassembly();

	LayoutGamepad(dp_xres, dp_yres);

	g_gameInfoCache.FlushBGs();

	NOTICE_LOG(BOOT, "Loading %s...", fileToStart.c_str());
}
Пример #2
0
void EmuScreen::sendMessage(const char *message, const char *value) {
	// External commands, like from the Windows UI.
	if (!strcmp(message, "pause")) {
		screenManager()->push(new GamePauseScreen(gamePath_));
	} else if (!strcmp(message, "stop")) {
		// We will push MainScreen in update().
		PSP_Shutdown();
	} else if (!strcmp(message, "reset")) {
		PSP_Shutdown();
		std::string resetError;
		if (!PSP_Init(PSP_CoreParameter(), &resetError)) {
			ELOG("Error resetting: %s", resetError.c_str());
			screenManager()->switchScreen(new MainScreen());
			System_SendMessage("event", "failstartgame");
			return;
		}
		host->BootDone();
		host->UpdateDisassembly();
#ifndef MOBILE_DEVICE
		if (g_Config.bAutoRun) {
			Core_EnableStepping(false);
		} else {
			Core_EnableStepping(true);
		}
#endif
	} else if (!strcmp(message, "boot")) {
		PSP_Shutdown();
		bootGame(value);
	} else if (!strcmp(message, "control mapping")) {
		UpdateUIState(UISTATE_MENU);
		screenManager()->push(new ControlMappingScreen());
	} else if (!strcmp(message, "settings")) {
		UpdateUIState(UISTATE_MENU);
		screenManager()->push(new GameSettingsScreen(gamePath_));
	} else if (!strcmp(message, "gpu resized") || !strcmp(message, "gpu clear cache")) {
		if (gpu) {
			gpu->ClearCacheNextFrame();
			gpu->Resized();
		}
		Reporting::UpdateConfig();
		RecreateViews();
	} else if (!strcmp(message, "gpu dump next frame")) {
		if (gpu) gpu->DumpNextFrame();
	} else if (!strcmp(message, "clear jit")) {
		if (MIPSComp::jit) {
			MIPSComp::jit->ClearCache();
		}
	}
}
Пример #3
0
EmuScreen::EmuScreen(const std::string &filename) : invalid_(true)
{
	std::string fileToStart = filename;
	// This is probably where we should start up the emulated PSP.
	INFO_LOG(BOOT, "Starting up hardware.");

	CoreParameter coreParam;
	coreParam.cpuCore = (CPUCore)g_Config.iCpuCore;
#if defined(ARM)
	if (coreParam.cpuCore == CPU_JIT)
		coreParam.cpuCore = CPU_FASTINTERPRETER;
#endif
	coreParam.gpuCore = GPU_GLES;
	coreParam.enableSound = g_Config.bEnableSound;
	coreParam.fileToStart = fileToStart;
	coreParam.mountIso = "";
	coreParam.startPaused = false;
	coreParam.enableDebugging = false;
	coreParam.printfEmuLog = false;
	coreParam.headLess = false;
	if (g_Config.iWindowZoom < 1 || g_Config.iWindowZoom > 2)
		g_Config.iWindowZoom = 1;
	coreParam.renderWidth = 480 * g_Config.iWindowZoom;
	coreParam.renderHeight = 272 * g_Config.iWindowZoom;
	coreParam.outputWidth = dp_xres;
	coreParam.outputHeight = dp_yres;
	coreParam.pixelWidth = pixel_xres;
	coreParam.pixelHeight = pixel_yres;
	coreParam.useMediaEngine = false;
	std::string error_string;
	if (PSP_Init(coreParam, &error_string)) {
		invalid_ = false;
	} else {
		invalid_ = true;
		errorMessage_ = error_string;
		ERROR_LOG(BOOT, "%s", errorMessage_.c_str());
		return;
	}

	LayoutGamepad(dp_xres, dp_yres);

	NOTICE_LOG(BOOT, "Loading %s...", fileToStart.c_str());
}
Пример #4
0
int main(int argc, const char* argv[])
{
	bool fullLog = false;
	bool useJit = false;
	bool fastInterpreter = false;
	bool autoCompare = false;
	bool useGraphics = false;
	
	const char *bootFilename = 0;
	const char *mountIso = 0;
	bool readMount = false;

	for (int i = 1; i < argc; i++)
	{
		if (readMount)
		{
			mountIso = argv[i];
			readMount = false;
			continue;
		}
		if (!strcmp(argv[i], "-m") || !strcmp(argv[i], "--mount"))
			readMount = true;
		else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--log"))
			fullLog = true;
		else if (!strcmp(argv[i], "-j"))
			useJit = true;
		else if (!strcmp(argv[i], "-f"))
			fastInterpreter = true;
		else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--compare"))
			autoCompare = true;
		else if (!strcmp(argv[i], "--graphics"))
			useGraphics = true;
		else if (bootFilename == 0)
			bootFilename = argv[i];
		else
		{
			if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
				printUsage(argv[0], NULL);
			else
			{
				std::string reason = "Unexpected argument " + std::string(argv[i]);
				printUsage(argv[0], reason.c_str());
			}
			return 1;
		}
	}

	if (readMount)
	{
		printUsage(argv[0], "Missing argument after -m");
		return 1;
	}
	if (!bootFilename)
	{
		printUsage(argv[0], argc <= 1 ? NULL : "No executable specified");
		return 1;
	}

	HeadlessHost *headlessHost = useGraphics ? new HEADLESSHOST_CLASS() : new HeadlessHost();
	host = headlessHost;
	host->InitGL();

	LogManager::Init();
	LogManager *logman = LogManager::GetInstance();
	
	PrintfLogger *printfLogger = new PrintfLogger();

	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
	{
		LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i;
		logman->SetEnable(type, fullLog);
		logman->SetLogLevel(type, LogTypes::LDEBUG);
		logman->AddListener(type, printfLogger);
	}

	CoreParameter coreParameter;
	coreParameter.fileToStart = bootFilename;
	coreParameter.mountIso = mountIso ? mountIso : "";
	coreParameter.startPaused = false;
	coreParameter.cpuCore = useJit ? CPU_JIT : (fastInterpreter ? CPU_FASTINTERPRETER : CPU_INTERPRETER);
	coreParameter.gpuCore = headlessHost->isGLWorking() ? GPU_GLES : GPU_NULL;
	coreParameter.enableSound = false;
	coreParameter.headLess = true;
	coreParameter.printfEmuLog = true;

	g_Config.bEnableSound = false;
	g_Config.bFirstRun = false;
	g_Config.bIgnoreBadMemAccess = true;

	std::string error_string;

	if (!PSP_Init(coreParameter, &error_string)) {
		fprintf(stderr, "Failed to start %s. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str());
		printf("TESTERROR\n");
		return 1;
	}

	host->BootDone();

	coreState = CORE_RUNNING;
	while (coreState == CORE_RUNNING)
	{
		// Run for a frame at a time, just because.
		u64 nowTicks = CoreTiming::GetTicks();
		u64 frameTicks = usToCycles(1000000/60);
		mipsr4k.RunLoopUntil(nowTicks + frameTicks);

		// If we were rendering, this might be a nice time to do something about it.
		if (coreState == CORE_NEXTFRAME)
			coreState = CORE_RUNNING;
	}

	host->ShutdownGL();
	PSP_Shutdown();

	delete host;
	host = NULL;
	headlessHost = NULL;

	if (autoCompare)
	{
		std::string expect_filename = std::string(bootFilename).substr(strlen(bootFilename - 4)) + ".expected";
		if (File::Exists(expect_filename))
		{
			// TODO: Do the compare here
		}
		else
		{
			fprintf(stderr, "Expectation file %s not found", expect_filename.c_str());
		}
	}

	return 0;
}
Пример #5
0
void RunTests()
{
	std::string output;

#ifdef IOS
	const std::string baseDirectory = g_Config.flash0Directory + "../";
#else
	const std::string baseDirectory = g_Config.memStickDirectory;
#endif

	CoreParameter coreParam;
	coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER;
	coreParam.gpuCore = g_Config.bSoftwareRendering ? GPU_SOFTWARE : GPU_GLES;
	coreParam.enableSound = g_Config.bEnableSound;
	coreParam.graphicsContext = PSP_CoreParameter().graphicsContext;
	coreParam.mountIso = "";
	coreParam.mountRoot = baseDirectory + "pspautotests/";
	coreParam.startPaused = false;
	coreParam.printfEmuLog = false;
	coreParam.headLess = true;
	coreParam.renderWidth = 480;
	coreParam.renderHeight = 272;
	coreParam.pixelWidth = 480;
	coreParam.pixelHeight = 272;
	coreParam.collectEmuLog = &output;
	coreParam.unthrottle = true;
	coreParam.updateRecent = false;

	// Never report from tests.
	std::string savedReportHost = g_Config.sReportHost;
	g_Config.sReportHost = "";

	for (size_t i = 0; i < ARRAY_SIZE(testsToRun); i++) {
		const char *testName = testsToRun[i];
		coreParam.fileToStart = baseDirectory + "pspautotests/tests/" + testName + ".prx";
		std::string expectedFile = baseDirectory + "pspautotests/tests/" + testName + ".expected";

		ILOG("Preparing to execute %s", testName);
		std::string error_string;
		output = "";
		if (!PSP_Init(coreParam, &error_string)) {
			ELOG("Failed to init unittest %s : %s", testsToRun[i], error_string.c_str());
			PSP_CoreParameter().pixelWidth = pixel_xres;
			PSP_CoreParameter().pixelHeight = pixel_yres;
			return;
		}

		// Run the emu until the test exits
		while (true) {
			int blockTicks = usToCycles(1000000 / 10);
			while (coreState == CORE_RUNNING) {
				PSP_RunLoopFor(blockTicks);
			}
			// Hopefully coreState is now CORE_NEXTFRAME
			if (coreState == CORE_NEXTFRAME) {
				// set back to running for the next frame
				coreState = CORE_RUNNING;
			} else if (coreState == CORE_POWERDOWN)	{
				ILOG("Finished running test %s", testName);
				break;
			}
		}
	
		std::ifstream expected(expectedFile.c_str(), std::ios_base::in);
		if (!expected) {
			ELOG("Error opening expectedFile %s", expectedFile.c_str());
			break;
		}

		std::istringstream logoutput(output);

		int line = 0;
		while (true) {
			++line;
			std::string e, o;
			std::getline(expected, e);
			std::getline(logoutput, o);
			// Remove stray returns
			e = TrimNewlines(e);
			o = TrimNewlines(o);
			if (e != o) {
				ELOG("DIFF on line %i!", line);
				ELOG("O: %s", o.c_str());
				ELOG("E: %s", e.c_str());
			}
			if (expected.eof()) {
				break;
			}
			if (logoutput.eof()) {
				break;
			}
		}
		PSP_Shutdown();
	}
	glViewport(0,0,pixel_xres,pixel_yres);
	PSP_CoreParameter().pixelWidth = pixel_xres;
	PSP_CoreParameter().pixelHeight = pixel_yres;
	PSP_CoreParameter().headLess = false;
	g_Config.sReportHost = savedReportHost;
}
Пример #6
0
void EmuScreen::bootGame(const std::string &filename) {
	booted_ = true;
	std::string fileToStart = filename;

	CoreParameter coreParam;
	coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER;
	coreParam.gpuCore = g_Config.bSoftwareRendering ? GPU_SOFTWARE : GPU_GLES;
	coreParam.enableSound = g_Config.bEnableSound;
	coreParam.fileToStart = fileToStart;
	coreParam.mountIso = "";
	coreParam.startPaused = false;
	coreParam.printfEmuLog = false;
	coreParam.headLess = false;

	if (g_Config.iInternalResolution == 0) {
		coreParam.renderWidth = dp_xres;
		coreParam.renderHeight = dp_yres;
	} else {
		if (g_Config.iInternalResolution < 0)
			g_Config.iInternalResolution = 1;
		coreParam.renderWidth = 480 * g_Config.iInternalResolution;
		coreParam.renderHeight = 272 * g_Config.iInternalResolution;
	}

	coreParam.outputWidth = dp_xres;
	coreParam.outputHeight = dp_yres;
	coreParam.pixelWidth = pixel_xres;
	coreParam.pixelHeight = pixel_yres;

	std::string error_string;
	if (PSP_Init(coreParam, &error_string)) {
		invalid_ = false;
	} else {
		invalid_ = true;
		errorMessage_ = error_string;
		ERROR_LOG(BOOT, "%s", errorMessage_.c_str());
		System_SendMessage("event", "failstartgame");
		return;
	}

	globalUIState = UISTATE_INGAME;
	host->BootDone();
	host->UpdateDisassembly();

	g_gameInfoCache.FlushBGs();

	NOTICE_LOG(BOOT, "Loading %s...", fileToStart.c_str());
	autoLoad();

	I18NCategory *s = GetI18NCategory("Screen"); 

#ifdef _WIN32
	if (g_Config.bFirstRun) {
		osm.Show(s->T("PressESC", "Press ESC to open the pause menu"), 3.0f);
	}
#endif
	memset(virtKeys, 0, sizeof(virtKeys));

	const char *renderer = (const char*)glGetString(GL_RENDERER);
	if (strstr(renderer, "Chainfire3D") != 0) {
		osm.Show(s->T("Chainfire3DWarning", "WARNING: Chainfire3D detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
	}

	System_SendMessage("event", "startgame");
}
Пример #7
0
// Main function
int main(int argc, char **argv)
{
	int battimeout = 0;
	char fpstxt[16];

	// Open debug files
	PokeDebugFOut = fopen("dbg_stdout.txt", "w");
	PokeDebugFErr = fopen("dbg_stderr.txt", "w");

	// Init video
	PokeDPrint(POKEMSG_OUT, "%s\n\n", AppName);
	PokeMini_InitDirs(argv[0], NULL);
	CommandLineInit();
	CommandLine.low_battery = 2;	// PSP can report battery status
	CommandLineConfFile("pokemini.cfg", "pokemini_psp.cfg", CustomConf);
	JoystickSetup("PSP", 0, 30000, PSP_KeysNames, 16, PSP_KeysMapping);

	// PSP Init and set screen
	PSP_Init();
	setup_screen();

	// Create emulator and load test roms
	PokeDPrint(POKEMSG_OUT, "Starting emulator...\n");
	PokeMini_Create(POKEMINI_GENSOUND | POKEMINI_AUTOBATT, 0);

	// Setup palette and LCD mode
	PokeMini_VideoPalette_Init(PokeMini_RGB16, 1);
	PokeMini_VideoPalette_Index(CommandLine.palette, CommandLine.custompal, CommandLine.lcdcontrast, CommandLine.lcdbright);
	PokeMini_ApplyChanges();

	// Load stuff
	PokeMini_UseDefaultCallbacks();
	if (!PokeMini_LoadFromCommandLines("Using FreeBIOS", "EEPROM data will be discarded!")) {
		UI_Status = UI_STATUS_MENU;
	}

	// Enable sound & init UI
	PokeDPrint(POKEMSG_OUT, "Running emulator...\n");
	UIMenu_Init();
	enablesound(CommandLine.sound);
	sceCtrlSetSamplingCycle(0);
	sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);

	// Emulator's loop
	u64 tickcurr;
	u64 fpsticknext,fpstickres = (u64)sceRtcGetTickResolution();
	u64 frmticknext, frmtickres = (u64)sceRtcGetTickResolution() / 36;
	sceRtcGetCurrentTick(&tickcurr);
	fpsticknext = tickcurr + fpstickres;
	frmticknext = tickcurr + frmtickres;
	int fps = 72, fpscnt = 0;
	strcpy(fpstxt, "");
	while (emurunning) {
		// Emulate 2 frames
		PokeMini_EmulateFrame();
		PokeMini_EmulateFrame();
		if (RequireSoundSync) {
			while (MinxAudio_SyncWithAudio()) sceKernelDelayThread(1000);
		} else {
			do {
				sceRtcGetCurrentTick(&tickcurr);
				sceKernelDelayThread(1000);
			} while (tickcurr < frmticknext);
			frmticknext = tickcurr + frmtickres;	// Aprox 36 times per sec
		}

		// Screen rendering
		PSP_ClearDraw();
		if (PokeMini_Rumbling) {
			PokeMini_VideoBlit((uint16_t *)PSP_DrawVideo + pm_offset + PokeMini_GenRumbleOffset(512), 512);
		} else {
			PokeMini_VideoBlit((uint16_t *)PSP_DrawVideo + pm_offset, 512);
		}
		LCDDirty = 0;

		// Display FPS counter
		if (clc_displayfps) {
			sceRtcGetCurrentTick(&tickcurr);
			if (tickcurr >= fpsticknext) {
				fpsticknext = tickcurr + fpstickres;
				fps = fpscnt;
				fpscnt = 0;
				sprintf(fpstxt, "%i FPS", fps);
			} else fpscnt++;
			UIDraw_String_16((uint16_t *)PSP_DrawVideo, 512, 4, 4, 10, fpstxt, UI_Font1_Pal16);
		}

		// Handle keys
		HandleKeys();

		// Menu
		if (UI_Status == UI_STATUS_MENU) menuloop();

		// Wait VSync & Render (72 Hz)
		PSP_Flip();

		// Check battery
		if (battimeout <= 0) {
			PokeMini_LowPower(scePowerIsLowBattery());
			battimeout = 600;
		} else battimeout--;
	}

	// Stop sound & free UI
	enablesound(0);
	UIMenu_Destroy();

	// Save Stuff
	PokeMini_SaveFromCommandLines(1);

	// Terminate...
	PokeDPrint(POKEMSG_OUT, "Shutdown emulator...\n");
	PokeMini_VideoPalette_Free();
	PokeMini_Destroy();

	// Close debug files
	fclose(PokeDebugFOut);
	fclose(PokeDebugFErr);

	// PSP Quit
	PSP_Quit();

	return 0;
}
Пример #8
0
int main(int argc, const char* argv[])
{
	bool fullLog = false;
	bool useJit = true;
	bool autoCompare = false;
	bool useGraphics = false;
	
	const char *bootFilename = 0;
	const char *mountIso = 0;
	const char *screenshotFilename = 0;
	bool readMount = false;

	for (int i = 1; i < argc; i++)
	{
		if (readMount)
		{
			mountIso = argv[i];
			readMount = false;
			continue;
		}
		if (!strcmp(argv[i], "-m") || !strcmp(argv[i], "--mount"))
			readMount = true;
		else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--log"))
			fullLog = true;
		else if (!strcmp(argv[i], "-i"))
			useJit = false;
		else if (!strcmp(argv[i], "-j"))
			useJit = true;
		else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--compare"))
			autoCompare = true;
		else if (!strcmp(argv[i], "--graphics"))
			useGraphics = true;
		else if (!strncmp(argv[i], "--screenshot=", strlen("--screenshot=")) && strlen(argv[i]) > strlen("--screenshot="))
			screenshotFilename = argv[i] + strlen("--screenshot=");
		else if (bootFilename == 0)
			bootFilename = argv[i];
		else
		{
			if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
				printUsage(argv[0], NULL);
			else
			{
				std::string reason = "Unexpected argument " + std::string(argv[i]);
				printUsage(argv[0], reason.c_str());
			}
			return 1;
		}
	}

	if (readMount)
	{
		printUsage(argv[0], "Missing argument after -m");
		return 1;
	}
	if (!bootFilename)
	{
		printUsage(argv[0], argc <= 1 ? NULL : "No executable specified");
		return 1;
	}

	HeadlessHost *headlessHost = useGraphics ? new HEADLESSHOST_CLASS() : new HeadlessHost();
	host = headlessHost;

	std::string error_string;
	bool glWorking = host->InitGL(&error_string);

	LogManager::Init();
	LogManager *logman = LogManager::GetInstance();
	
	PrintfLogger *printfLogger = new PrintfLogger();

	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
	{
		LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i;
		logman->SetEnable(type, fullLog);
		logman->SetLogLevel(type, LogTypes::LDEBUG);
		logman->AddListener(type, printfLogger);
	}

	CoreParameter coreParameter;
	coreParameter.cpuCore = useJit ? CPU_JIT : CPU_INTERPRETER;
	coreParameter.gpuCore = glWorking ? GPU_GLES : GPU_NULL;
	coreParameter.enableSound = false;
	coreParameter.fileToStart = bootFilename;
	coreParameter.mountIso = mountIso ? mountIso : "";
	coreParameter.startPaused = false;
	coreParameter.enableDebugging = false;
	coreParameter.printfEmuLog = true;
	coreParameter.headLess = true;
	coreParameter.renderWidth = 480;
	coreParameter.renderHeight = 272;
	coreParameter.outputWidth = 480;
	coreParameter.outputHeight = 272;
	coreParameter.pixelWidth = 480;
	coreParameter.pixelHeight = 272;
	coreParameter.unthrottle = true;

	g_Config.bEnableSound = false;
	g_Config.bFirstRun = false;
	g_Config.bIgnoreBadMemAccess = true;
	// Never report from tests.
	g_Config.sReportHost = "";
	g_Config.bAutoSaveSymbolMap = false;
	g_Config.iRenderingMode = true;
	g_Config.bHardwareTransform = true;
#ifdef USING_GLES2
	g_Config.iAnisotropyLevel = 0;
#else
	g_Config.iAnisotropyLevel = 8;
#endif
	g_Config.bVertexCache = true;
	g_Config.bTrueColor = true;
	g_Config.ilanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
	g_Config.iTimeFormat = PSP_SYSTEMPARAM_TIME_FORMAT_24HR;
	g_Config.bEncryptSave = true;
	g_Config.sNickName = "shadow";
	g_Config.iTimeZone = 60;
	g_Config.iDateFormat = PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY;
	g_Config.iButtonPreference = PSP_SYSTEMPARAM_BUTTON_CROSS;
	g_Config.iLockParentalLevel = 9;

#if defined(ANDROID)
#elif defined(BLACKBERRY) || defined(__SYMBIAN32__)
#elif !defined(_WIN32)
	g_Config.memCardDirectory = std::string(getenv("HOME"))+"/.ppsspp/";
	g_Config.flashDirectory = g_Config.memCardDirectory+"/flash/";
#endif

	if (!PSP_Init(coreParameter, &error_string)) {
		fprintf(stderr, "Failed to start %s. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str());
		printf("TESTERROR\n");
		return 1;
	}

	host->BootDone();

	if (screenshotFilename != 0)
		headlessHost->SetComparisonScreenshot(screenshotFilename);

	coreState = CORE_RUNNING;
	while (coreState == CORE_RUNNING)
	{
		int blockTicks = usToCycles(1000000 / 10);
		PSP_RunLoopFor(blockTicks);

		// If we were rendering, this might be a nice time to do something about it.
		if (coreState == CORE_NEXTFRAME) {
			coreState = CORE_RUNNING;
			headlessHost->SwapBuffers();
		}
	}

	host->ShutdownGL();
	PSP_Shutdown();

	delete host;
	host = NULL;
	headlessHost = NULL;

	if (autoCompare)
		CompareOutput(bootFilename);

	return 0;
}
Пример #9
0
bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool autoCompare, bool verbose, double timeout)
{
	if (teamCityMode) {
		// Kinda ugly, trying to guesstimate the test name from filename...
		teamCityName = GetTestName(coreParameter.fileToStart);
	}

	std::string output;
	if (autoCompare)
		coreParameter.collectEmuLog = &output;

	std::string error_string;
	if (!PSP_Init(coreParameter, &error_string)) {
		fprintf(stderr, "Failed to start %s. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str());
		printf("TESTERROR\n");
		TeamCityPrint("##teamcity[testIgnored name='%s' message='PRX/ELF missing']\n", teamCityName.c_str());
		return false;
	}

	TeamCityPrint("##teamcity[testStarted name='%s' captureStandardOutput='true']\n", teamCityName.c_str());

	host->BootDone();

	if (autoCompare)
		headlessHost->SetComparisonScreenshot(ExpectedScreenshotFromFilename(coreParameter.fileToStart));

	time_update();
	bool passed = true;
	// TODO: We must have some kind of stack overflow or we're not following the ABI right.
	// This gets trashed if it's not static.
	static double deadline;
	deadline = time_now() + timeout;

	coreState = CORE_RUNNING;
	while (coreState == CORE_RUNNING)
	{
		int blockTicks = usToCycles(1000000 / 10);
		PSP_RunLoopFor(blockTicks);

		// If we were rendering, this might be a nice time to do something about it.
		if (coreState == CORE_NEXTFRAME) {
			coreState = CORE_RUNNING;
			headlessHost->SwapBuffers();
		}
		time_update();
		if (time_now_d() > deadline) {
			// Don't compare, print the output at least up to this point, and bail.
			printf("%s", output.c_str());
			passed = false;

			host->SendDebugOutput("TIMEOUT\n");
			TeamCityPrint("##teamcity[testFailed name='%s' message='Test timeout']\n", teamCityName.c_str());
			Core_Stop();
		}
	}

	PSP_Shutdown();

	headlessHost->FlushDebugOutput();

	if (autoCompare && passed)
		passed = CompareOutput(coreParameter.fileToStart, output, verbose);

	TeamCityPrint("##teamcity[testFinished name='%s']\n", teamCityName.c_str());

	return passed;
}
Пример #10
0
void EmuThread::run()
{
	running = true;
	setCurrentThreadName("EmuThread");

	host->UpdateUI();
	host->InitGL();

	glWindow->makeCurrent();

#ifndef USING_GLES2
	glewInit();
#endif
	NativeInitGraphics();

	INFO_LOG(BOOT, "Starting up hardware.");

	QElapsedTimer timer;

	while(running) {
		//UpdateGamepad(*input_state);
		timer.start();

		gameMutex.lock();
		bool gRun = gameRunning;
		gameMutex.unlock();

		if(gRun)
		{
			gameMutex.lock();

			glWindow->makeCurrent();
			if(needInitGame)
			{
				g_State.bEmuThreadStarted = true;

				CoreParameter coreParameter;
				coreParameter.fileToStart = fileToStart.toStdString();
				coreParameter.enableSound = true;
				coreParameter.gpuCore = GPU_GLES;
				coreParameter.cpuCore = (CPUCore)g_Config.iCpuCore;
				coreParameter.enableDebugging = true;
				coreParameter.printfEmuLog = false;
				coreParameter.headLess = false;
				coreParameter.renderWidth = 480 * g_Config.iWindowZoom;
				coreParameter.renderHeight = 272 * g_Config.iWindowZoom;
				coreParameter.outputWidth = dp_xres;
				coreParameter.outputHeight = dp_yres;
				coreParameter.pixelWidth = pixel_xres;
				coreParameter.pixelHeight = pixel_yres;
				coreParameter.startPaused = !g_Config.bAutoRun;

				std::string error_string;
				if (!PSP_Init(coreParameter, &error_string))
				{
					ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str());
					FinalShutdown();
					return;
				}

				LayoutGamepad(dp_xres, dp_yres);

				_dbg_update_();

				host->UpdateDisassembly();
				Core_EnableStepping(coreParameter.startPaused ? TRUE : FALSE);

				g_State.bBooted = true;
			#ifdef _DEBUG
				host->UpdateMemView();
			#endif
				host->BootDone();
				needInitGame = false;
			}
			UpdateInputState(input_state);

			for (int i = 0; i < controllistCount; i++) {
				if (input_state->pad_buttons_down & controllist[i].emu_id) {
					__CtrlButtonDown(controllist[i].psp_id);
				}
				if (input_state->pad_buttons_up & controllist[i].emu_id) {
					__CtrlButtonUp(controllist[i].psp_id);
				}
			}
			__CtrlSetAnalog(input_state->pad_lstick_x, input_state->pad_lstick_y);

			EndInputState(input_state);

			glstate.Restore();
			glViewport(0, 0, pixel_xres, pixel_yres);
			Matrix4x4 ortho;
			ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f);
			glsl_bind(UIShader_Get());
			glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr());


			ReapplyGfxState();

			Core_Run();

			// Hopefully coreState is now CORE_NEXTFRAME
			if (coreState == CORE_NEXTFRAME) {
				// set back to running for the next frame
				coreState = CORE_RUNNING;

				qint64 time = timer.elapsed();
				const int frameTime = (1.0f/60.0f) * 1000;
				gameMutex.unlock();
				if(time < frameTime)
				{
					glWindow->doneCurrent();
					msleep(frameTime-time);
					glWindow->makeCurrent();
				}
				gameMutex.lock();
				timer.start();
			}

			fbo_unbind();

			UIShader_Prepare();

			uiTexture->Bind(0);

			glViewport(0, 0, pixel_xres, pixel_yres);

			ui_draw2d.Begin(DBMODE_NORMAL);

			//if (g_Config.bShowTouchControls)
			//	DrawGamepad(ui_draw2d);

			glsl_bind(UIShader_Get());
			ui_draw2d.End();
			ui_draw2d.Flush(UIShader_Get());


			// Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it?
#if defined(USING_GLES2)
			bool hasDiscard = false;  // TODO
			if (hasDiscard) {
				//glDiscardFramebuffer(GL_COLOR_EXT | GL_DEPTH_EXT | GL_STENCIL_EXT);
			}
#endif
			glWindow->swapBuffers();
			glWindow->doneCurrent();
			gameMutex.unlock();
		}
		else
		{
			gameMutex.lock();
			glWindow->makeCurrent();
			glClearColor(0, 0, 0, 0);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

			time_update();
			float t = (float)frames_ / 60.0f;
			frames_++;

			float alpha = t;
			if (t > 1.0f) alpha = 1.0f;
			float alphaText = alpha;
			//if (t > 2.0f) alphaText = 3.0f - t;

			glstate.Restore();
			glViewport(0, 0, pixel_xres, pixel_yres);
			Matrix4x4 ortho;
			ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f);
			glsl_bind(UIShader_Get());
			glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr());


			ReapplyGfxState();

			UIShader_Prepare();
			UIBegin();
			DrawBackground(alpha);

			ui_draw2d.SetFontScale(1.5f, 1.5f);
			ui_draw2d.DrawText(UBUNTU48, "PPSSPP", dp_xres / 2, dp_yres / 2 - 30, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
			ui_draw2d.SetFontScale(1.0f, 1.0f);
			ui_draw2d.DrawText(UBUNTU24, "Created by Henrik Rydgard", dp_xres / 2, dp_yres / 2 + 40, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
			ui_draw2d.DrawText(UBUNTU24, "Free Software under GPL 2.0", dp_xres / 2, dp_yres / 2 + 70, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
			ui_draw2d.DrawText(UBUNTU24, "www.ppsspp.org", dp_xres / 2, dp_yres / 2 + 130, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);

			UIEnd();

			glsl_bind(UIShader_Get());
			ui_draw2d.Flush(UIShader_Get());

			glWindow->swapBuffers();
			glWindow->doneCurrent();
			gameMutex.unlock();
			qint64 time = timer.elapsed();
			const int frameTime = (1.0f/60.0f) * 1000;
			if(time < frameTime)
			{
				msleep(frameTime-time);
			}
			timer.start();
		}

	}

	if(gameRunning)
	{
		stopGame();
	}

}
Пример #11
0
int main(int argc, char **argv)
{
    int rank = 0;

    command_name = argv[0];
    parse_opt(argc, argv);

    if (arg_version) {
	printVersion();
	return 0;
    }

    if (arg_cp) {
	unsigned int slen = strlen(copy_command_src) + strlen(arg_cp) + 1000;
	char *icmd = malloc(slen);
	snprintf(icmd, slen,"%s %s", copy_command_src, arg_cp);
	arg_icmd = icmd;
	arg_ocmd = copy_command_dest;

	fprintf(stderr, " input command: %s\n", arg_icmd);
    }

    if (arg_icmd && arg_ifile) {
	fprintf(stderr, "Warning: Ignoring -icmd %s, because -i is set\n",
		arg_icmd);
	arg_icmd = NULL;
    }
    if (arg_ocmd && arg_ofile) {
	fprintf(stderr, "Warning: Ignoring -ocmd %s, because -o is set\n",
		arg_ocmd);
	arg_ocmd = NULL;
    }

    if (PSP_Init() != PSP_OK) {
	fprintf(stderr, "PSP_Init() failed!\n");
	exit(1);
    }

    if (!arg_manual) {
	/* HACK HACK HACK */
	setenv("__PSI_MASTERNODE", "-1", 0);
	setenv("__PSI_MASTERPORT", "-1", 0);
	PSE_initialize();

	rank = PSE_getRank();
    } else if (arg_server) {
	rank = 1;
    }

    if (rank < 0) {
	/* original process, let's spawn rank 0 and become logger */
	setenv("PSI_NOMSGLOGGERDONE", "", 1);
	PSE_spawnAdmin(-1, 0, argc, argv, 0);
    } else if (rank == 0) {
	/* server */
	if (arg_progress) set_timer(1, 1 ,timer);
	doServer();
    } else {
	/* client */
	if (arg_progress && arg_manual) set_timer(1, 1 ,timer);
	doClient();
    }

    if (!arg_manual) {
	PSI_release(PSC_getMyTID());
    }

    if ((!rank || arg_manual) && arg_progress) {
	print_stat(1);
    }

    return 0;
}
Пример #12
0
int main(int argc, const char* argv[])
{
	bool fullLog = false;
	bool useJit = true;
	bool autoCompare = false;
	bool useGraphics = false;
	
	const char *bootFilename = 0;
	const char *mountIso = 0;
	const char *screenshotFilename = 0;
	bool readMount = false;

	for (int i = 1; i < argc; i++)
	{
		if (readMount)
		{
			mountIso = argv[i];
			readMount = false;
			continue;
		}
		if (!strcmp(argv[i], "-m") || !strcmp(argv[i], "--mount"))
			readMount = true;
		else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--log"))
			fullLog = true;
		else if (!strcmp(argv[i], "-i"))
			useJit = false;
		else if (!strcmp(argv[i], "-j"))
			useJit = true;
		else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--compare"))
			autoCompare = true;
		else if (!strcmp(argv[i], "--graphics"))
			useGraphics = true;
		else if (!strncmp(argv[i], "--screenshot=", strlen("--screenshot=")) && strlen(argv[i]) > strlen("--screenshot="))
			screenshotFilename = argv[i] + strlen("--screenshot=");
		else if (bootFilename == 0)
			bootFilename = argv[i];
		else
		{
			if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
				printUsage(argv[0], NULL);
			else
			{
				std::string reason = "Unexpected argument " + std::string(argv[i]);
				printUsage(argv[0], reason.c_str());
			}
			return 1;
		}
	}

	if (readMount)
	{
		printUsage(argv[0], "Missing argument after -m");
		return 1;
	}
	if (!bootFilename)
	{
		printUsage(argv[0], argc <= 1 ? NULL : "No executable specified");
		return 1;
	}

	HeadlessHost *headlessHost = useGraphics ? new HEADLESSHOST_CLASS() : new HeadlessHost();
	host = headlessHost;

	std::string error_string;
	host->InitGL(&error_string);

	LogManager::Init();
	LogManager *logman = LogManager::GetInstance();
	
	PrintfLogger *printfLogger = new PrintfLogger();

	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
	{
		LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i;
		logman->SetEnable(type, fullLog);
		logman->SetLogLevel(type, LogTypes::LDEBUG);
		logman->AddListener(type, printfLogger);
	}

	CoreParameter coreParameter;
	coreParameter.fileToStart = bootFilename;
	coreParameter.mountIso = mountIso ? mountIso : "";
	coreParameter.startPaused = false;
	coreParameter.cpuCore = useJit ? CPU_JIT : CPU_INTERPRETER;
	coreParameter.gpuCore = headlessHost->isGLWorking() ? GPU_GLES : GPU_NULL;
	coreParameter.enableSound = false;
	coreParameter.headLess = true;
	coreParameter.printfEmuLog = true;
	coreParameter.useMediaEngine = false;

	g_Config.bEnableSound = false;
	g_Config.bFirstRun = false;
	g_Config.bIgnoreBadMemAccess = true;
	// Never report from tests.
	g_Config.sReportHost = "";

#if defined(ANDROID)
#elif defined(BLACKBERRY) || defined(__SYMBIAN32__)
#elif !defined(_WIN32)
	g_Config.memCardDirectory = std::string(getenv("HOME"))+"/.ppsspp/";
	g_Config.flashDirectory = g_Config.memCardDirectory+"/flash/";
#endif


	if (!PSP_Init(coreParameter, &error_string)) {
		fprintf(stderr, "Failed to start %s. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str());
		printf("TESTERROR\n");
		return 1;
	}

	host->BootDone();

	if (screenshotFilename != 0)
		headlessHost->SetComparisonScreenshot(screenshotFilename);

	coreState = CORE_RUNNING;
	while (coreState == CORE_RUNNING)
	{
		// Run for a frame at a time, just because.
		u64 nowTicks = CoreTiming::GetTicks();
		u64 frameTicks = usToCycles(1000000/60);
		mipsr4k.RunLoopUntil(nowTicks + frameTicks);

		// If we were rendering, this might be a nice time to do something about it.
		if (coreState == CORE_NEXTFRAME) {
			coreState = CORE_RUNNING;
			headlessHost->SwapBuffers();
		}
	}

	host->ShutdownGL();
	PSP_Shutdown();

	delete host;
	host = NULL;
	headlessHost = NULL;

	if (autoCompare)
		CompareOutput(bootFilename);

	return 0;
}
Пример #13
0
int main(int argc, const char* argv[])
{
	bool fullLog = false;
	bool useJit = false;
	bool autoCompare = false;
	
	const char *bootFilename = argc > 1 ? argv[1] : 0;
	const char *mountIso = 0;
	bool readMount = false;

	for (int i = 2; i < argc; i++)
	{
		if (readMount)
		{
			mountIso = argv[i];
			readMount = false;
			continue;
		}
		if (!strcmp(argv[i], "-m"))
			readMount = true;
		else if (!strcmp(argv[i], "-l"))
			fullLog = true;
		else if (!strcmp(argv[i], "-j"))
			useJit = true;
		else if (!strcmp(argv[i], "-c"))
			autoCompare = true;
	}

	if (!bootFilename)
	{
		printUsage();
		return 1;
	}

	host = new HeadlessHost();

	LogManager::Init();
	LogManager *logman = LogManager::GetInstance();
	
	PrintfLogger *printfLogger = new PrintfLogger();

	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
	{
		LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i;
		logman->SetEnable(type, fullLog);
		logman->SetLogLevel(type, LogTypes::LDEBUG);
		logman->AddListener(type, printfLogger);
	}

	CoreParameter coreParameter;
	coreParameter.fileToStart = bootFilename;
	coreParameter.mountIso = mountIso ? mountIso : "";
	coreParameter.startPaused = false;
	coreParameter.cpuCore = useJit ? CPU_JIT : CPU_INTERPRETER;
	coreParameter.gpuCore = GPU_NULL;
	coreParameter.enableSound = false;
	coreParameter.headLess = true;
	coreParameter.printfEmuLog = true;

	g_Config.bEnableSound = false;
	g_Config.bFirstRun = false;
	g_Config.bIgnoreBadMemAccess = true;

	std::string error_string;

	if (!PSP_Init(coreParameter, &error_string)) {
		fprintf(stderr, "Failed to start %s. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str());
		printf("TESTERROR\n");
		return 1;
	}

	coreState = CORE_RUNNING;

	while (coreState == CORE_RUNNING)
	{
		// Run for a frame at a time, just because.
		u64 nowTicks = CoreTiming::GetTicks();
		u64 frameTicks = usToCycles(1000000/60);
		mipsr4k.RunLoopUntil(nowTicks + frameTicks);
	}

	// NOTE: we won't get here until I've gotten rid of the exit(0) in sceExitProcess or whatever it's called

	PSP_Shutdown();

	if (autoCompare)
	{
		std::string expect_filename = std::string(bootFilename).substr(strlen(bootFilename - 4)) + ".expected";
		if (File::Exists(expect_filename))
		{
			// TODO: Do the compare here
		}
		else
		{
			fprintf(stderr, "Expectation file %s not found", expect_filename.c_str());
		}
	}

	return 0;
}
Пример #14
0
void RunTests()
{
	std::string output;

	CoreParameter coreParam;
	coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER;
	coreParam.gpuCore = GPU_GLES;
	coreParam.enableSound = g_Config.bEnableSound;
	coreParam.mountIso = "";
	coreParam.startPaused = false;
	coreParam.enableDebugging = false;
	coreParam.printfEmuLog = false;
	coreParam.headLess = false;
	coreParam.renderWidth = 480;
	coreParam.renderHeight = 272;
	coreParam.outputWidth = 480;
	coreParam.outputHeight = 272;
	coreParam.pixelWidth = 480;
	coreParam.pixelHeight = 272;
	coreParam.useMediaEngine = false;
	coreParam.collectEmuLog = &output;

	// Never report from tests.
	std::string savedReportHost = g_Config.sReportHost;
	g_Config.sReportHost = "";

	for (int i = 0; i < ARRAY_SIZE(testsToRun); i++) {
		const char *testName = testsToRun[i];
		coreParam.fileToStart = g_Config.memCardDirectory + "pspautotests/tests/" + testName + ".prx";
		std::string expectedFile =  g_Config.memCardDirectory + "pspautotests/tests/" + testName + ".expected";

		ILOG("Preparing to execute %s", testName)
		std::string error_string;
		output = "";
		if (!PSP_Init(coreParam, &error_string)) {
			ELOG("Failed to init unittest %s : %s", testsToRun[i], error_string.c_str());
			return;
		}

		// Run the emu until the test exits
		while (true) {
			int blockTicks = usToCycles(1000000 / 10);
			while (coreState == CORE_RUNNING) {
				u64 nowTicks = CoreTiming::GetTicks();
				mipsr4k.RunLoopUntil(nowTicks + blockTicks);
			}
			// Hopefully coreState is now CORE_NEXTFRAME
			if (coreState == CORE_NEXTFRAME) {
				// set back to running for the next frame
				coreState = CORE_RUNNING;
			} else if (coreState == CORE_POWERDOWN)	{
				ILOG("Finished running test %s", testName);
				break;
			}
		}
	
		std::ifstream expected(expectedFile.c_str(), std::ios_base::in);
		if (!expected) {
			ELOG("Error opening expectedFile %s", expectedFile.c_str());
			return;
		}

		std::istringstream logoutput(output);

		int line = 0;
		while (true) {
			++line;
			std::string e, o;
			std::getline(expected, e);
			std::getline(logoutput, o);
			// Remove stray returns
			while (e[e.size()-1] == 10 || e[e.size()-1] == 13)
				e = e.substr(0, e.size() - 1);  // For some reason we get some extra character
			while (o[o.size()-1] == 10 || o[o.size()-1] == 13)
				o = o.substr(0, o.size() - 1);  // For some reason we get some extra character
			if (e != o) {
				ELOG("DIFF on line %i!", line);
				ILOG("O: %s", o.c_str());
				ILOG("E: %s", e.c_str());
			}
			if (expected.eof()) {
				break;
			}
			if (logoutput.eof()) {
				break;
			}
		}
		PSP_Shutdown();
	}
	glstate.Restore();
	glstate.viewport.set(0,0,pixel_xres,pixel_yres);

	g_Config.sReportHost = savedReportHost;
}
Пример #15
0
DWORD TheThread(LPVOID x)
{
	setCurrentThreadName("EmuThread");

	g_State.bEmuThreadStarted = true;

	host->UpdateUI();
	host->InitGL();

	INFO_LOG(BOOT, "Starting up hardware.");

  CoreParameter coreParameter;
  coreParameter.fileToStart = fileToStart;
  coreParameter.enableSound = true;
  coreParameter.gpuCore = GPU_GLES;
  coreParameter.cpuCore = g_Config.bJIT ? CPU_JIT : CPU_INTERPRETER;
  coreParameter.enableDebugging = true;
  coreParameter.printfEmuLog = false;
  coreParameter.headLess = false; //true;

	std::string error_string;
	if (!PSP_Init(coreParameter, &error_string))
	{
		ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str());
		goto shutdown;
	}

	INFO_LOG(BOOT, "Done.");
	_dbg_update_();

	if (g_Config.bAutoRun)
	{
#ifdef _DEBUG
		host->UpdateDisassembly();
#endif
		Core_EnableStepping(FALSE);
	}
	else
	{
#ifdef _DEBUG
		host->UpdateDisassembly();
#endif
		Core_EnableStepping(TRUE);
	}

	g_State.bBooted = true;
#ifdef _DEBUG
	host->UpdateMemView();
#endif

	host->BootDone();
	Core_Run();

	host->PrepareShutdown();


	PSP_Shutdown();

shutdown:

	host->ShutdownGL();
	
	//The CPU should return when a game is stopped and cleanup should be done here, 
	//so we can restart the plugins (or load new ones) for the next game
	g_State.bEmuThreadStarted = false;
	_endthreadex(0);
	return 0;
}
Пример #16
0
void EmuThread::run()
{
	running = true;
	setCurrentThreadName("EmuThread");

	g_State.bEmuThreadStarted = true;

	host->UpdateUI();
	host->InitGL();

	glWindow->makeCurrent();

#ifndef USING_GLES2
	glewInit();
#endif
	NativeInitGraphics();

	INFO_LOG(BOOT, "Starting up hardware.");

	CoreParameter coreParameter;
	coreParameter.fileToStart = fileToStart.toStdString();
	coreParameter.enableSound = true;
	coreParameter.gpuCore = GPU_GLES;
	coreParameter.cpuCore = (CPUCore)g_Config.iCpuCore;
	coreParameter.enableDebugging = true;
	coreParameter.printfEmuLog = false;
	coreParameter.headLess = false;
	coreParameter.renderWidth = 480 * g_Config.iWindowZoom;
	coreParameter.renderHeight = 272 * g_Config.iWindowZoom;
	coreParameter.outputWidth = dp_xres;
	coreParameter.outputHeight = dp_yres;
	coreParameter.pixelWidth = pixel_xres;
	coreParameter.pixelHeight = pixel_yres;
	coreParameter.startPaused = !g_Config.bAutoRun;

	std::string error_string;
	if (!PSP_Init(coreParameter, &error_string))
	{
		ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str());
		FinalShutdown();
		return;
	}

	LayoutGamepad(dp_xres, dp_yres);

	_dbg_update_();

	host->UpdateDisassembly();
	Core_EnableStepping(coreParameter.startPaused ? TRUE : FALSE);

	g_State.bBooted = true;
#ifdef _DEBUG
	host->UpdateMemView();
#endif
	host->BootDone();

	QElapsedTimer timer;

	while(running) {
		//UpdateGamepad(*input_state);
		timer.start();

		UpdateInputState(input_state);

		static const int mapping[12][2] = {
			{PAD_BUTTON_A, CTRL_CROSS},
			{PAD_BUTTON_B, CTRL_CIRCLE},
			{PAD_BUTTON_X, CTRL_SQUARE},
			{PAD_BUTTON_Y, CTRL_TRIANGLE},
			{PAD_BUTTON_UP, CTRL_UP},
			{PAD_BUTTON_DOWN, CTRL_DOWN},
			{PAD_BUTTON_LEFT, CTRL_LEFT},
			{PAD_BUTTON_RIGHT, CTRL_RIGHT},
			{PAD_BUTTON_LBUMPER, CTRL_LTRIGGER},
			{PAD_BUTTON_RBUMPER, CTRL_RTRIGGER},
			{PAD_BUTTON_START, CTRL_START},
			{PAD_BUTTON_SELECT, CTRL_SELECT},
		};

		for (int i = 0; i < 12; i++) {
            if (input_state->pad_buttons_down & mapping[i][0]) {
				__CtrlButtonDown(mapping[i][1]);
			}
            if (input_state->pad_buttons_up & mapping[i][0]) {
				__CtrlButtonUp(mapping[i][1]);
			}
		}
		__CtrlSetAnalog(input_state->pad_lstick_x, input_state->pad_lstick_y);

		EndInputState(input_state);

		glstate.Restore();
		glViewport(0, 0, pixel_xres, pixel_yres);
		Matrix4x4 ortho;
		ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f);
		glsl_bind(UIShader_Get());
		glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr());


		ReapplyGfxState();

		Core_Run();

		// Hopefully coreState is now CORE_NEXTFRAME
		if (coreState == CORE_NEXTFRAME) {
			// set back to running for the next frame
			coreState = CORE_RUNNING;

			qint64 time = timer.elapsed();
			const int frameTime = (1.0f/60.0f) * 1000;
			if(time < frameTime)
			{
				msleep(frameTime-time);
			}
			timer.start();
		}

		fbo_unbind();

		UIShader_Prepare();

		uiTexture->Bind(0);

		glViewport(0, 0, pixel_xres, pixel_yres);

		ui_draw2d.Begin(DBMODE_NORMAL);

		//if (g_Config.bShowTouchControls)
		//	DrawGamepad(ui_draw2d);

		glsl_bind(UIShader_Get());
		ui_draw2d.End();
		ui_draw2d.Flush(UIShader_Get());


		// Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it?
#if defined(USING_GLES2)
		bool hasDiscard = false;  // TODO
		if (hasDiscard) {
			//glDiscardFramebuffer(GL_COLOR_EXT | GL_DEPTH_EXT | GL_STENCIL_EXT);
		}
#endif

		glWindow->swapBuffers();
	}
	glWindow->doneCurrent();
}