void EmuScreen::render() { if (invalid_) return; // Reapply the graphics state of the PSP ReapplyGfxState(); // We just run the CPU until we get to vblank. This will quickly sync up pretty nicely. // The actual number of cycles doesn't matter so much here as we will break due to CORE_NEXTFRAME, most of the time hopefully... int blockTicks = usToCycles(1000000 / 10); // Run until CORE_NEXTFRAME 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("SELF-POWERDOWN!"); screenManager()->switchScreen(new MenuScreen()); } if (invalid_) return; if (g_Config.bBufferedRendering) fbo_unbind(); UIShader_Prepare(); uiTexture->Bind(0); glstate.viewport.set(0, 0, pixel_xres, pixel_yres); glstate.viewport.restore(); ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL); if (g_Config.bShowTouchControls) DrawGamepad(ui_draw2d); DrawWatermark(); if (g_Config.bShowDebugStats) { char statbuf[4096] = {0}; __DisplayGetDebugStats(statbuf); if (statbuf[4095]) ERROR_LOG(HLE, "Statbuf too big"); ui_draw2d.SetFontScale(.7f, .7f); ui_draw2d.DrawText(UBUNTU24, statbuf, 11, 11, 0xc0000000); ui_draw2d.DrawText(UBUNTU24, statbuf, 10, 10, 0xFFFFFFFF); ui_draw2d.SetFontScale(1.0f, 1.0f); } if (g_Config.bShowFPSCounter) { float vps, fps; __DisplayGetFPS(&vps, &fps); char fpsbuf[256]; sprintf(fpsbuf, "VPS: %0.1f", vps); ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 8, 12, 0xc0000000, ALIGN_TOPRIGHT); ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT); } glsl_bind(UIShader_Get()); ui_draw2d.End(); ui_draw2d.Flush(); // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? #if defined(USING_GLES2) bool hasDiscard = gl_extensions.EXT_discard_framebuffer; // TODO if (hasDiscard) { //const GLenum targets[3] = { GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT }; //glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, targets); } #endif }
void InGameMenuScreen::update(InputState &input) { if (input.pad_buttons_down & PAD_BUTTON_BACK) { screenManager()->finishDialog(this, DR_CANCEL); } }
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(); bootPending_ = false; invalid_ = true; host->UpdateDisassembly(); } else if (!strcmp(message, "reset")) { PSP_Shutdown(); bootPending_ = true; invalid_ = true; host->UpdateDisassembly(); std::string resetError; if (!PSP_InitStart(PSP_CoreParameter(), &resetError)) { ELOG("Error resetting: %s", resetError.c_str()); screenManager()->switchScreen(new MainScreen()); System_SendMessage("event", "failstartgame"); return; } } else if (!strcmp(message, "boot")) { const char *ext = strrchr(value, '.'); if (!strcmp(ext, ".ppst")) { SaveState::Load(value, &AfterStateLoad); } else { PSP_Shutdown(); bootPending_ = true; 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(); } if (PSP_IsInited()) { currentMIPS->UpdateCore(g_Config.bJit ? CPU_JIT : CPU_INTERPRETER); } } else if (!strcmp(message, "window minimized")) { if (!strcmp(value, "true")) { gstate_c.skipDrawReason |= SKIPDRAW_WINDOW_MINIMIZED; } else { gstate_c.skipDrawReason &= ~SKIPDRAW_WINDOW_MINIMIZED; } } }
void EmuScreen::update(InputState &input) { if (bootPending_) bootGame(gamePath_); UIScreen::update(input); // Simply forcibily update to the current screen size every frame. Doesn't cost much. // If bounds is set to be smaller than the actual pixel resolution of the display, respect that. // TODO: Should be able to use g_dpi_scale here instead. Might want to store the dpi scale in the UI context too. const Bounds &bounds = screenManager()->getUIContext()->GetBounds(); PSP_CoreParameter().pixelWidth = pixel_xres * bounds.w / dp_xres; PSP_CoreParameter().pixelHeight = pixel_yres * bounds.h / dp_yres; if (!invalid_) { UpdateUIState(UISTATE_INGAME); } if (errorMessage_.size()) { // Special handling for ZIP files. It's not very robust to check an error message but meh, // at least it's pre-translation. if (errorMessage_.find("ZIP") != std::string::npos) { screenManager()->push(new InstallZipScreen(gamePath_)); errorMessage_ = ""; quit_ = true; return; } I18NCategory *g = GetI18NCategory("Error"); std::string errLoadingFile = g->T("Error loading file", "Could not load game"); errLoadingFile.append(" "); errLoadingFile.append(g->T(errorMessage_.c_str())); screenManager()->push(new PromptScreen(errLoadingFile, "OK", "")); errorMessage_ = ""; quit_ = true; return; } if (invalid_) return; // Virtual keys. __CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]); // Apply tilt to left stick // TODO: Make into an axis #ifdef MOBILE_DEVICE /* if (g_Config.bAccelerometerToAnalogHoriz) { // Get the "base" coordinate system which is setup by the calibration system float base_x = g_Config.fTiltBaseX; float base_y = g_Config.fTiltBaseY; //convert the current input into base coordinates and normalize //TODO: check if all phones give values between [-50, 50]. I'm not sure how iOS works. float normalized_input_x = (input.acc.y - base_x) / 50.0 ; float normalized_input_y = (input.acc.x - base_y) / 50.0 ; //TODO: need a better name for computed x and y. float delta_x = tiltInputCurve(normalized_input_x * 2.0 * (g_Config.iTiltSensitivityX)) ; //if the invert is enabled, invert the motion if (g_Config.bInvertTiltX) { delta_x *= -1; } float delta_y = tiltInputCurve(normalized_input_y * 2.0 * (g_Config.iTiltSensitivityY)) ; if (g_Config.bInvertTiltY) { delta_y *= -1; } //clamp the delta between [-1, 1] leftstick_x += clamp1(delta_x); __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); leftstick_y += clamp1(delta_y); __CtrlSetAnalogY(clamp1(leftstick_y), CTRL_STICK_LEFT); } */ #endif // Make sure fpsLimit starts at 0 if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1) { PSP_CoreParameter().fpsLimit = 0; } // This is here to support the iOS on screen back button. if (pauseTrigger_) { pauseTrigger_ = false; screenManager()->push(new GamePauseScreen(gamePath_)); } }
void ErrorScreen::update(InputState &input_state) { if (input_state.pad_buttons_down & PAD_BUTTON_BACK) { screenManager()->finishDialog(this, DR_OK); } }
void EmuScreen::render() { if (invalid_) return; // Reapply the graphics state of the PSP ReapplyGfxState(); // We just run the CPU until we get to vblank. This will quickly sync up pretty nicely. // The actual number of cycles doesn't matter so much here as we will break due to CORE_NEXTFRAME, most of the time hopefully... int blockTicks = usToCycles(1000000 / 10); // Run until CORE_NEXTFRAME 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("SELF-POWERDOWN!"); if (g_Config.bNewUI) screenManager()->switchScreen(new MainScreen()); else screenManager()->switchScreen(new MenuScreen()); } if (invalid_) return; bool useBufferedRendering = g_Config.iRenderingMode != 0 ? 1 : 0; if (useBufferedRendering) fbo_unbind(); UIShader_Prepare(); uiTexture->Bind(0); glstate.viewport.set(0, 0, pixel_xres, pixel_yres); glstate.viewport.restore(); ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL); float touchOpacity = g_Config.iTouchButtonOpacity / 100.0f; if (root_) { UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_); root_->Draw(*screenManager()->getUIContext()); } DrawWatermark(); if (!osm.IsEmpty()) { osm.Draw(ui_draw2d); } if (g_Config.bShowDebugStats) { char statbuf[4096] = {0}; __DisplayGetDebugStats(statbuf); if (statbuf[4095]) ERROR_LOG(HLE, "Statbuf too big"); ui_draw2d.SetFontScale(.7f, .7f); ui_draw2d.DrawText(UBUNTU24, statbuf, 11, 11, 0xc0000000); ui_draw2d.DrawText(UBUNTU24, statbuf, 10, 10, 0xFFFFFFFF); ui_draw2d.SetFontScale(1.0f, 1.0f); } if (g_Config.iShowFPSCounter) { float vps, fps; __DisplayGetFPS(&vps, &fps); char fpsbuf[256]; switch (g_Config.iShowFPSCounter) { case 1: sprintf(fpsbuf, "Speed: %0.1f%%", vps / 60.0f * 100.0f); break; case 2: sprintf(fpsbuf, "FPS: %0.1f", fps); break; case 3: sprintf(fpsbuf, "Speed: %0.1f%%\nFPS: %0.1f", vps / 60.0f * 100.0f, fps); break; } ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 8, 12, 0xc0000000, ALIGN_TOPRIGHT); ui_draw2d.DrawText(UBUNTU24, fpsbuf, dp_xres - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT); } glsl_bind(UIShader_Get()); ui_draw2d.End(); ui_draw2d.Flush(); // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? #if defined(USING_GLES2) bool hasDiscard = gl_extensions.EXT_discard_framebuffer; // TODO if (hasDiscard) { //const GLenum targets[3] = { GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT }; //glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, targets); } #endif }
void PauseScreen::update(InputState &input) { globalUIState = UISTATE_PAUSEMENU; if (input.pad_buttons_down & PAD_BUTTON_BACK) { screenManager()->finishDialog(this, DR_CANCEL); } }
void FileSelectScreen::update(InputState &input_state) { if (input_state.pad_buttons_down & PAD_BUTTON_BACK) { g_Config.Save(); screenManager()->switchScreen(new MenuScreen()); } }
void MenuScreen::sendMessage(const char *message, const char *value) { if (!strcmp(message, "boot")) { screenManager()->switchScreen(new EmuScreen(value)); } }
void MenuScreen::render() { UIShader_Prepare(); UIBegin(UIShader_Get()); DrawBackground(1.0f); double xoff = 150 - frames_ * frames_ * 0.4f; if (xoff < -20) xoff = -20; if (frames_ > 200) // seems the above goes nuts after a while... xoff = -20; int w = LARGE_BUTTON_WIDTH + 60; ui_draw2d.DrawTextShadow(UBUNTU48, "PPSSPP", dp_xres + xoff - w/2, 75, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_BOTTOM); ui_draw2d.SetFontScale(0.7f, 0.7f); ui_draw2d.DrawTextShadow(UBUNTU24, PPSSPP_GIT_VERSION, dp_xres + xoff, 85, 0xFFFFFFFF, ALIGN_RIGHT | ALIGN_BOTTOM); ui_draw2d.SetFontScale(1.0f, 1.0f); VLinear vlinear(dp_xres + xoff, 100, 20); I18NCategory *m = GetI18NCategory("MainMenu"); if (UIButton(GEN_ID, vlinear, w, 0, m->T("Load", "Load..."), ALIGN_RIGHT)) { #if defined(USING_QT_UI) && !defined(MEEGO_EDITION_HARMATTAN) QString fileName = QFileDialog::getOpenFileName(NULL, "Load ROM", g_Config.currentDirectory.c_str(), "PSP ROMs (*.iso *.cso *.pbp *.elf)"); if (QFile::exists(fileName)) { QDir newPath; g_Config.currentDirectory = newPath.filePath(fileName).toStdString(); g_Config.Save(); screenManager()->switchScreen(new EmuScreen(fileName.toStdString())); } #elif _WIN32 MainWindow::BrowseAndBoot(""); #else FileSelectScreenOptions options; options.allowChooseDirectory = true; options.filter = "iso:cso:pbp:elf:prx:"; options.folderIcon = I_ICON_FOLDER; options.iconMapping["iso"] = I_ICON_UMD; options.iconMapping["cso"] = I_ICON_UMD; options.iconMapping["pbp"] = I_ICON_EXE; options.iconMapping["elf"] = I_ICON_EXE; screenManager()->switchScreen(new FileSelectScreen(options)); #endif UIReset(); } if (UIButton(GEN_ID, vlinear, w, 0, m->T("Settings"), ALIGN_RIGHT)) { screenManager()->push(new SettingsScreen(), 0); UIReset(); } if (UIButton(GEN_ID, vlinear, w, 0, m->T("Credits"), ALIGN_RIGHT)) { screenManager()->switchScreen(new CreditsScreen()); UIReset(); } if (UIButton(GEN_ID, vlinear, w, 0, m->T("Exit"), ALIGN_RIGHT)) { // TODO: Save when setting changes, rather than when we quit NativeShutdown(); // TODO: Need a more elegant way to quit #ifdef _WIN32 ExitProcess(0); #else exit(0); #endif } if (UIButton(GEN_ID, vlinear, w, 0, "www.ppsspp.org", ALIGN_RIGHT)) { LaunchBrowser("http://www.ppsspp.org/"); } int recentW = 350; if (g_Config.recentIsos.size()) { ui_draw2d.DrawText(UBUNTU24, m->T("Recent"), -xoff, 80, 0xFFFFFFFF, ALIGN_BOTTOMLEFT); } int spacing = 15; float textureButtonWidth = 144; float textureButtonHeight = 80; if (dp_yres < 480) spacing = 8; // On small screens, we can't fit four vertically. if (100 + spacing * 6 + textureButtonHeight * 4 > dp_yres) { textureButtonHeight = (dp_yres - 100 - spacing * 6) / 4; textureButtonWidth = (textureButtonHeight / 80) * 144; } VGrid vgrid_recent(-xoff, 100, std::min(dp_yres-spacing*2, 480), spacing, spacing); for (size_t i = 0; i < g_Config.recentIsos.size(); i++) { std::string filename; std::string rec = g_Config.recentIsos[i]; for (size_t j = 0; j < rec.size(); j++) if (rec[j] == '\\') rec[j] = '/'; SplitPath(rec, nullptr, &filename, nullptr); UIContext *ctx = screenManager()->getUIContext(); // This might create a texture so we must flush first. UIFlush(); GameInfo *ginfo = g_gameInfoCache.GetInfo(g_Config.recentIsos[i], false); if (ginfo && ginfo->fileType != FILETYPE_PSP_ELF) { u32 color; if (ginfo->iconTexture == 0) { color = 0; } else { color = whiteAlpha(ease((time_now_d() - ginfo->timeIconWasLoaded) * 2)); } if (UITextureButton(ctx, (int)GEN_ID_LOOP(i), vgrid_recent, textureButtonWidth, textureButtonHeight, ginfo->iconTexture, ALIGN_LEFT, color, I_DROP_SHADOW)) { UIEnd(); screenManager()->switchScreen(new EmuScreen(g_Config.recentIsos[i])); return; } } else { if (UIButton((int)GEN_ID_LOOP(i), vgrid_recent, textureButtonWidth, textureButtonHeight, filename.c_str(), ALIGN_LEFT)) { UIEnd(); screenManager()->switchScreen(new EmuScreen(g_Config.recentIsos[i])); return; } } } #if defined(_DEBUG) & defined(_WIN32) // Print the current dp_xres/yres in the corner. For UI scaling testing - just // resize to 800x480 to get an idea of what it will look like on a Nexus S. ui_draw2d.SetFontScale(0.4, 0.4); char temptext[64]; sprintf(temptext, "%ix%i", dp_xres, dp_yres); ui_draw2d.DrawTextShadow(UBUNTU24, temptext, 5, dp_yres-5, 0xFFFFFFFF, ALIGN_BOTTOMLEFT); ui_draw2d.SetFontScale(1.0, 1.0); #endif DrawWatermark(); UIEnd(); }
void EmuScreen::bootGame(const std::string &filename) { if (PSP_IsIniting()) { std::string error_string; bootPending_ = !PSP_InitUpdate(&error_string); if (!bootPending_) { invalid_ = !PSP_IsInited(); if (invalid_) { errorMessage_ = error_string; ERROR_LOG(BOOT, "%s", errorMessage_.c_str()); System_SendMessage("event", "failstartgame"); return; } bootComplete(); } return; } //pre-emptive loading of game specific config if possible, to get all the settings GameInfo *info = g_gameInfoCache.GetInfo(NULL, filename, 0); if (info && !info->id.empty()) { g_Config.loadGameConfig(info->id); } invalid_ = true; CoreParameter coreParam; coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER; coreParam.gpuCore = g_Config.bSoftwareRendering ? GPU_SOFTWARE : GPU_GLES; if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) { coreParam.gpuCore = GPU_DIRECTX9; } coreParam.enableSound = g_Config.bEnableSound; coreParam.fileToStart = filename; coreParam.mountIso = ""; coreParam.mountRoot = ""; coreParam.startPaused = false; coreParam.printfEmuLog = false; coreParam.headLess = false; const Bounds &bounds = screenManager()->getUIContext()->GetBounds(); if (g_Config.iInternalResolution == 0) { coreParam.renderWidth = bounds.w; coreParam.renderHeight = bounds.h; } else { if (g_Config.iInternalResolution < 0) g_Config.iInternalResolution = 1; coreParam.renderWidth = 480 * g_Config.iInternalResolution; coreParam.renderHeight = 272 * g_Config.iInternalResolution; } std::string error_string; if (!PSP_InitStart(coreParam, &error_string)) { bootPending_ = false; invalid_ = true; errorMessage_ = error_string; ERROR_LOG(BOOT, "%s", errorMessage_.c_str()); System_SendMessage("event", "failstartgame"); } }
void EmuScreen::update(InputState &input) { globalUIState = UISTATE_INGAME; if (errorMessage_.size()) { screenManager()->push(new PromptScreen( "Error loading file: " + errorMessage_, "OK", "")); errorMessage_ = ""; return; } if (invalid_) return; float leftstick_x = 0.0f; float leftstick_y = 0.0f; float rightstick_x = 0.0f; float rightstick_y = 0.0f; // Virtual keys. __CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]); // First translate touches into native pad input. // Do this no matter the value of g_Config.bShowTouchControls, some people // like to use invisible controls... // Don't force on platforms that likely don't have a touchscreen, like Win32, OSX, and Linux... // TODO: What are good ifdefs for OSX and Linux, without breaking other mobile platforms? #ifdef _WIN32 if(g_Config.bShowTouchControls) { #endif // TODO: Make new better touch buttons so we don't have to do this crap. // Copy over the mouse data from the real inputstate. fakeInputState.mouse_valid = input.mouse_valid; fakeInputState.pad_last_buttons = fakeInputState.pad_buttons; fakeInputState.pad_buttons = input.pad_buttons; memcpy(fakeInputState.pointer_down, input.pointer_down, sizeof(input.pointer_down)); memcpy(fakeInputState.pointer_x, input.pointer_x, sizeof(input.pointer_x)); memcpy(fakeInputState.pointer_y, input.pointer_y, sizeof(input.pointer_y)); fakeInputState.pad_lstick_x = 0.0f; fakeInputState.pad_lstick_y = 0.0f; fakeInputState.pad_rstick_x = 0.0f; fakeInputState.pad_rstick_y = 0.0f; UpdateGamepad(fakeInputState); UpdateInputState(&fakeInputState, true); for (size_t i = 0; i < ARRAY_SIZE(legacy_touch_mapping); i++) { if (fakeInputState.pad_buttons_down & legacy_touch_mapping[i].from) __CtrlButtonDown(legacy_touch_mapping[i].to); if (fakeInputState.pad_buttons_up & legacy_touch_mapping[i].from) __CtrlButtonUp(legacy_touch_mapping[i].to); } leftstick_x += fakeInputState.pad_lstick_x; leftstick_y += fakeInputState.pad_lstick_y; rightstick_x += fakeInputState.pad_rstick_x; rightstick_y += fakeInputState.pad_rstick_y; if (g_Config.bShowAnalogStick) { __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); __CtrlSetAnalogY(clamp1(leftstick_y), CTRL_STICK_LEFT); } __CtrlSetAnalogX(clamp1(rightstick_x), CTRL_STICK_RIGHT); __CtrlSetAnalogY(clamp1(rightstick_y), CTRL_STICK_RIGHT); // Also send the special buttons to input, since that's where they're handled. input.pad_buttons_down |= fakeInputState.pad_buttons_down & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB | PAD_BUTTON_LEFT_THUMB); input.pad_buttons_up |= fakeInputState.pad_buttons_up & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB | PAD_BUTTON_LEFT_THUMB); input.pad_buttons = fakeInputState.pad_buttons; #ifdef _WIN32 } #endif // Still checking input.pad_buttons here to support the onscreen throttle button. PSP_CoreParameter().unthrottle = virtKeys[VIRTKEY_UNTHROTTLE - VIRTKEY_FIRST] || (input.pad_buttons & PAD_BUTTON_UNTHROTTLE) != 0; // Apply tilt to left stick if (g_Config.bAccelerometerToAnalogHoriz) { // TODO: Deadzone, etc. leftstick_x += clamp1(curve1(input.acc.y) * 2.0f); __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); } // Make sure fpsLimit starts at 0 if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1) { PSP_CoreParameter().fpsLimit = 0; } // This is still here to support the iOS on screen back button. if (input.pad_buttons_down & (PAD_BUTTON_BACK)) { screenManager()->push(new PauseScreen()); } }
void LanguageScreen::render() { UIShader_Prepare(); UIBegin(UIShader_Get()); DrawBackground(1.0f); I18NCategory *s = GetI18NCategory("System"); I18NCategory *g = GetI18NCategory("General"); I18NCategory *l = GetI18NCategory("Language"); ui_draw2d.SetFontScale(1.5f, 1.5f); ui_draw2d.DrawText(UBUNTU24, s->T("Language"), dp_xres / 2, 20, 0xFFFFFFFF, ALIGN_HCENTER); ui_draw2d.SetFontScale(1.0f, 1.0f); if (UIButton(GEN_ID, Pos(dp_xres - 10, dp_yres-10), LARGE_BUTTON_WIDTH, 0, g->T("Back"), ALIGN_RIGHT | ALIGN_BOTTOM)) { screenManager()->finishDialog(this, DR_OK); } VGrid vlang(50, 100, dp_yres - 50, 10, 10); for (size_t i = 0; i < langs_.size(); i++) { std::string code; size_t dot = langs_[i].name.find('.'); if (dot != std::string::npos) code = langs_[i].name.substr(0, dot); std::string buttonTitle = langs_[i].name; if (!code.empty()) buttonTitle = code; if (UIButton(GEN_ID_LOOP(i), vlang, LARGE_BUTTON_WIDTH - 40, 0, buttonTitle.c_str(), ALIGN_TOPLEFT)) { std::string oldLang = g_Config.languageIni; g_Config.languageIni = code; if (i18nrepo.LoadIni(g_Config.languageIni)) { // Dunno what else to do here. langValuesMapping["ja_JP"] = PSP_SYSTEMPARAM_LANGUAGE_JAPANESE; langValuesMapping["en_US"] = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; langValuesMapping["fr_FR"] = PSP_SYSTEMPARAM_LANGUAGE_FRENCH; langValuesMapping["es_ES"] = PSP_SYSTEMPARAM_LANGUAGE_SPANISH; langValuesMapping["es_LA"] = PSP_SYSTEMPARAM_LANGUAGE_SPANISH; langValuesMapping["de_DE"] = PSP_SYSTEMPARAM_LANGUAGE_GERMAN; langValuesMapping["it_IT"] = PSP_SYSTEMPARAM_LANGUAGE_ITALIAN; langValuesMapping["nl_NL"] = PSP_SYSTEMPARAM_LANGUAGE_DUTCH; langValuesMapping["pt_BR"] = PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE; langValuesMapping["ru_RU"] = PSP_SYSTEMPARAM_LANGUAGE_RUSSIAN; langValuesMapping["ko_KR"] = PSP_SYSTEMPARAM_LANGUAGE_KOREAN; langValuesMapping["zh_TW"] = PSP_SYSTEMPARAM_LANGUAGE_CHINESE_TRADITIONAL; langValuesMapping["zh_CN"] = PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED; if(langValuesMapping.find(code) == langValuesMapping.end()) { //Fallback to English g_Config.ilanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; } else { g_Config.ilanguage = langValuesMapping[code]; } // After this, g and s are no longer valid. Let's return, some flicker is okay. g = GetI18NCategory("General"); s = GetI18NCategory("System"); l = GetI18NCategory("Language"); } else { g_Config.languageIni = oldLang; } } } UIEnd(); }
void InGameMenuScreen::render() { UIShader_Prepare(); UIBegin(); DrawBackground(1.0f); const char *title; if (UTF8StringHasNonASCII(game_title.c_str())) { title = "(can't display japanese title)"; } else { title = game_title.c_str(); } ui_draw2d.DrawText(UBUNTU48, title, dp_xres / 2, 30, 0xFFFFFFFF, ALIGN_HCENTER); int x = 30; int y = 50; UICheckBox(GEN_ID, x, y += 50, "Show Debug Statistics", ALIGN_TOPLEFT, &g_Config.bShowDebugStats); UICheckBox(GEN_ID, x, y += 50, "Show FPS", ALIGN_TOPLEFT, &g_Config.bShowFPSCounter); // TODO: Maybe shouldn't show this if the screen ratios are very close... UICheckBox(GEN_ID, x, y += 50, "Stretch to display", ALIGN_TOPLEFT, &g_Config.bStretchToDisplay); UICheckBox(GEN_ID, x, y += 50, "Hardware Transform", ALIGN_TOPLEFT, &g_Config.bHardwareTransform); bool fs = g_Config.iFrameSkip == 1; UICheckBox(GEN_ID, x, y += 50, "Frameskip", ALIGN_TOPLEFT, &fs); g_Config.iFrameSkip = fs ? 1 : 0; // TODO: Add UI for more than one slot. HLinear hlinear1(x, y + 80, 20); if (UIButton(GEN_ID, hlinear1, LARGE_BUTTON_WIDTH, "Save State", ALIGN_LEFT)) { SaveState::SaveSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } if (UIButton(GEN_ID, hlinear1, LARGE_BUTTON_WIDTH, "Load State", ALIGN_LEFT)) { SaveState::LoadSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } VLinear vlinear(dp_xres - 10, 160, 20); if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH, "Continue", ALIGN_RIGHT)) { screenManager()->finishDialog(this, DR_CANCEL); } if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH, "Settings", ALIGN_RIGHT)) { screenManager()->push(new SettingsScreen(), 0); } if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH, "Return to Menu", ALIGN_RIGHT)) { screenManager()->finishDialog(this, DR_OK); } /* if (UIButton(GEN_ID, Pos(dp_xres - 10, dp_yres - 10), LARGE_BUTTON_WIDTH*2, "Debug: Dump Next Frame", ALIGN_BOTTOMRIGHT)) { gpu->DumpNextFrame(); } */ DrawWatermark(); UIEnd(); glsl_bind(UIShader_Get()); ui_draw2d.Flush(UIShader_Get()); }
void PauseScreen::sendMessage(const char *msg, const char *value) { if (!strcmp(msg, "run")) { screenManager()->finishDialog(this, DR_CANCEL); } }
void SettingsScreen::update(InputState &input) { if (input.pad_buttons_down & PAD_BUTTON_BACK) { g_Config.Save(); screenManager()->finishDialog(this, DR_OK); } }
void PauseScreen::render() { UIShader_Prepare(); UIBegin(UIShader_Get()); DrawBackground(1.0f); std::string title = game_title.c_str(); // Try to ignore (tm) etc. //if (UTF8StringNonASCIICount(game_title.c_str()) > 2) { // title = "(can't display japanese title)"; //} else { //} UIContext *ctx = screenManager()->getUIContext(); // This might create a texture so we must flush first. UIFlush(); GameInfo *ginfo = g_gameInfoCache.GetInfo(PSP_CoreParameter().fileToStart, true); if (ginfo) { title = ginfo->title; } if (ginfo && ginfo->pic1Texture) { ginfo->pic1Texture->Bind(0); uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timePic1WasLoaded) * 3)) & 0xFFc0c0c0; ui_draw2d.DrawTexRect(0,0,dp_xres, dp_yres, 0,0,1,1,color); ui_draw2d.Flush(); ctx->RebindTexture(); } if (ginfo && ginfo->pic0Texture) { ginfo->pic0Texture->Bind(0); // Pic0 is drawn in the bottom right corner, overlaying pic1. float sizeX = dp_xres / 480 * ginfo->pic0Texture->Width(); float sizeY = dp_yres / 272 * ginfo->pic0Texture->Height(); uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timePic1WasLoaded) * 2)) & 0xFFc0c0c0; ui_draw2d.DrawTexRect(dp_xres - sizeX, dp_yres - sizeY, dp_xres, dp_yres, 0,0,1,1,color); ui_draw2d.Flush(); ctx->RebindTexture(); } if (ginfo && ginfo->iconTexture) { uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timeIconWasLoaded) * 1.5)); ginfo->iconTexture->Bind(0); // Maintain the icon's aspect ratio. Minis are square, for example. float iconAspect = (float)ginfo->iconTexture->Width() / (float)ginfo->iconTexture->Height(); float h = 80.0f; float w = 144.0f; float x = 10.0f + (w - h * iconAspect) / 2.0f; w = h * iconAspect; ui_draw2d.DrawTexRect(x, 10, x + w, 10 + h, 0, 0, 1, 1, 0xFFFFFFFF); ui_draw2d.Flush(); ctx->RebindTexture(); } ui_draw2d.DrawText(UBUNTU24, title.c_str(), 10+144+10, 30, 0xFFFFFFFF, ALIGN_LEFT); int x = 30; int y = 50; int stride = 40; int columnw = 400; // Shared with settings I18NCategory *ss = GetI18NCategory("System"); I18NCategory *gs = GetI18NCategory("Graphics"); I18NCategory *a = GetI18NCategory("Audio"); UICheckBox(GEN_ID, x, y += stride, ss->T("Show FPS"), ALIGN_TOPLEFT, &g_Config.bShowFPSCounter); UICheckBox(GEN_ID, x, y += stride, a->T("Enable Sound"), ALIGN_TOPLEFT, &g_Config.bEnableSound); // TODO: Maybe shouldn't show this if the screen ratios are very close... UICheckBox(GEN_ID, x, y += stride, gs->T("Stretch to Display"), ALIGN_TOPLEFT, &g_Config.bStretchToDisplay); UICheckBox(GEN_ID, x, y += stride, gs->T("Hardware Transform"), ALIGN_TOPLEFT, &g_Config.bHardwareTransform); if (UICheckBox(GEN_ID, x, y += stride, gs->T("Buffered Rendering"), ALIGN_TOPLEFT, &g_Config.bBufferedRendering)) { if (gpu) gpu->Resized(); } UICheckBox(GEN_ID, x, y += stride, gs->T("Media Engine"), ALIGN_TOPLEFT, &g_Config.bUseMediaEngine); bool enableFrameSkip = g_Config.iFrameSkip != 0; UICheckBox(GEN_ID, x, y += stride, gs->T("Frame Skipping"), ALIGN_TOPLEFT, &enableFrameSkip); if (enableFrameSkip) { if (g_Config.iFrameSkip == 0) g_Config.iFrameSkip = 3; ui_draw2d.DrawText(UBUNTU24, gs->T("Frames :"), x + 60, y += stride, 0xFFFFFFFF, ALIGN_LEFT); HLinear hlinear1(x + 200 , y + 5, 20); if (UIButton(GEN_ID, hlinear1, 80, 0, "Auto", ALIGN_LEFT)) g_Config.iFrameSkip = 3; if (UIButton(GEN_ID, hlinear1, 30, 0, "1", ALIGN_LEFT)) g_Config.iFrameSkip = 1; if (UIButton(GEN_ID, hlinear1, 30, 0, "2", ALIGN_LEFT)) g_Config.iFrameSkip = 2; } else { g_Config.iFrameSkip = 0; } I18NCategory *i = GetI18NCategory("Pause"); // TODO: Add UI for more than one slot. HLinear hlinear1(x, y + 80, 20); if (UIButton(GEN_ID, hlinear1, LARGE_BUTTON_WIDTH, 0, i->T("Save State"), ALIGN_LEFT)) { SaveState::SaveSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } if (UIButton(GEN_ID, hlinear1, LARGE_BUTTON_WIDTH, 0, i->T("Load State"), ALIGN_LEFT)) { SaveState::LoadSlot(0, 0, 0); screenManager()->finishDialog(this, DR_CANCEL); } VLinear vlinear(dp_xres - 10, 160, 20); if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 20, 0, i->T("Continue"), ALIGN_RIGHT)) { screenManager()->finishDialog(this, DR_CANCEL); } if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 20, 0, i->T("Settings"), ALIGN_RIGHT)) { screenManager()->push(new SettingsScreen(), 0); } if (UIButton(GEN_ID, vlinear, LARGE_BUTTON_WIDTH + 20, 0, i->T("Back to Menu"), ALIGN_RIGHT)) { screenManager()->finishDialog(this, DR_OK); } /* if (UIButton(GEN_ID, Pos(dp_xres - 10, dp_yres - 10), LARGE_BUTTON_WIDTH*2, 0, "Debug: Dump Next Frame", ALIGN_BOTTOMRIGHT)) { gpu->DumpNextFrame(); } */ DrawWatermark(); UIEnd(); }
void CreditsScreen::update(InputState &input_state) { if (input_state.pad_buttons_down & PAD_BUTTON_BACK) { screenManager()->switchScreen(new MenuScreen()); } frames_++; }
void GraphicsScreenP2::render() { UIShader_Prepare(); UIBegin(UIShader_Get()); DrawBackground(1.0f); I18NCategory *g = GetI18NCategory("General"); I18NCategory *gs = GetI18NCategory("Graphics"); ui_draw2d.SetFontScale(1.5f, 1.5f); ui_draw2d.DrawText(UBUNTU24, gs->T("Graphics Settings"), dp_xres / 2, 20, 0xFFFFFFFF, ALIGN_HCENTER); ui_draw2d.SetFontScale(1.0f, 1.0f); if (UIButton(GEN_ID, Pos(dp_xres - 10, dp_yres - 10), LARGE_BUTTON_WIDTH, 0, g->T("Back"), ALIGN_RIGHT | ALIGN_BOTTOM)) { screenManager()->finishDialog(this, DR_OK); } int x = 30; int y = 30; int stride = 40; int columnw = 400; if (g_Config.bBufferedRendering) { if (UICheckBox(GEN_ID, x, y += stride, gs->T("AA", "Anti Aliasing"), ALIGN_TOPLEFT, &g_Config.SSAntiAliasing)) { if (gpu) gpu->Resized(); } } UICheckBox(GEN_ID, x, y += stride, gs->T("Draw Wireframe"), ALIGN_TOPLEFT, &g_Config.bDrawWireframe); UICheckBox(GEN_ID, x, y += stride, gs->T("Display Raw Framebuffer"), ALIGN_TOPLEFT, &g_Config.bDisplayFramebuffer); UICheckBox(GEN_ID, x, y += stride, gs->T("True Color"), ALIGN_TOPLEFT, &g_Config.bTrueColor); bool AnisotropicFiltering = g_Config.iAnisotropyLevel != 0; UICheckBox(GEN_ID, x, y += stride, gs->T("Anisotropic Filtering"), ALIGN_TOPLEFT, &AnisotropicFiltering); if (AnisotropicFiltering) { if (g_Config.iAnisotropyLevel == 0) g_Config.iAnisotropyLevel = 2; ui_draw2d.DrawText(UBUNTU24, gs->T("Level :"), x + 60, y += stride - 5, 0xFFFFFFFF, ALIGN_LEFT); HLinear hlinear1(x + 160 , y + 5, 20); if (UIButton(GEN_ID, hlinear1, 45, 0, "2x", ALIGN_LEFT)) g_Config.iAnisotropyLevel = 2; if (UIButton(GEN_ID, hlinear1, 45, 0, "4x", ALIGN_LEFT)) g_Config.iAnisotropyLevel = 4; if (UIButton(GEN_ID, hlinear1, 45, 0, "8x", ALIGN_LEFT)) g_Config.iAnisotropyLevel = 8; if (UIButton(GEN_ID, hlinear1, 60, 0, "16x", ALIGN_LEFT)) g_Config.iAnisotropyLevel = 16; } else { g_Config.iAnisotropyLevel = 0; } bool TexScaling = g_Config.iTexScalingLevel > 1; UICheckBox(GEN_ID, x, y += stride + 20, gs->T("xBRZ Texture Scaling"), ALIGN_TOPLEFT, &TexScaling); if (TexScaling) { if (g_Config.iTexScalingLevel <= 1) g_Config.iTexScalingLevel = 2; ui_draw2d.DrawText(UBUNTU24, gs->T("Level :"), x + 60, y += stride + 5, 0xFFFFFFFF, ALIGN_LEFT); HLinear hlinear1(x + 160 , y - 5, 20); if (UIButton(GEN_ID, hlinear1, 45, 0, "2x", ALIGN_LEFT)) g_Config.iTexScalingLevel = 2; if (UIButton(GEN_ID, hlinear1, 45, 0, "3x", ALIGN_LEFT)) g_Config.iTexScalingLevel = 3; HLinear hlinear2(x + 160 , y + 60, 20); ui_draw2d.DrawText(UBUNTU24, gs->T("Type :"), x + 60, y += stride + 20, 0xFFFFFFFF, ALIGN_LEFT); if (UIButton(GEN_ID, hlinear2, 90, 0, "xBRZ", ALIGN_LEFT)) g_Config.iTexScalingType = 0; if (UIButton(GEN_ID, hlinear2, 100, 0, "Hybrid", ALIGN_LEFT)) g_Config.iTexScalingType = 1; } else { g_Config.iTexScalingLevel = 1; } UIEnd(); }
void EmuScreen::update(InputState &input) { globalUIState = UISTATE_INGAME; if (errorMessage_.size()) { screenManager()->push(new ErrorScreen( "Error loading file", errorMessage_)); errorMessage_ = ""; return; } if (invalid_) return; // First translate touches into native pad input. // Do this no matter the value of g_Config.bShowTouchControls, some people // like to use invisible controls... UpdateGamepad(input); UpdateInputState(&input); // Then translate pad input into PSP pad input. Also, add in tilt. 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.pad_buttons_down & mapping[i][0]) { __CtrlButtonDown(mapping[i][1]); } if (input.pad_buttons_up & mapping[i][0]) { __CtrlButtonUp(mapping[i][1]); } } float stick_x = input.pad_lstick_x; float stick_y = input.pad_lstick_y; float rightstick_x = input.pad_rstick_x; float rightstick_y = input.pad_rstick_y; I18NCategory *s = GetI18NCategory("Screen"); // Apply tilt to left stick if (g_Config.bAccelerometerToAnalogHoriz) { // TODO: Deadzone, etc. stick_x += clamp1(curve1(input.acc.y) * 2.0f); stick_x = clamp1(stick_x); } __CtrlSetAnalog(stick_x, stick_y, 0); __CtrlSetAnalog(rightstick_x, rightstick_x, 1); if (PSP_CoreParameter().fpsLimit != 2) { if (input.pad_buttons_down & PAD_BUTTON_UNTHROTTLE) { osm.Show(s->T("unlimited", "Speed: unlimited!"), 1.0, 0x50E0FF); } if (input.pad_buttons_up & PAD_BUTTON_UNTHROTTLE) { osm.Show(s->T("standard", "Speed: standard"), 1.0); } } if (input.pad_buttons & PAD_BUTTON_UNTHROTTLE) { PSP_CoreParameter().unthrottle = true; } else { PSP_CoreParameter().unthrottle = false; } // Make sure fpsLimit starts at 0 if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1 && PSP_CoreParameter().fpsLimit != 2) { PSP_CoreParameter().fpsLimit = 0; } //Toggle between 3 different states of fpsLimit if (input.pad_buttons_down & PAD_BUTTON_LEFT_THUMB) { if (PSP_CoreParameter().fpsLimit == 0) { PSP_CoreParameter().fpsLimit = 1; osm.Show(s->T("fixed", "Speed: fixed"), 1.0); } else if (PSP_CoreParameter().fpsLimit == 1){ PSP_CoreParameter().fpsLimit = 2; osm.Show(s->T("unlimited", "Speed: unlimited!"), 1.0, 0x50E0FF); } else if (PSP_CoreParameter().fpsLimit == 2){ PSP_CoreParameter().fpsLimit = 0; osm.Show(s->T("standard", "Speed: standard"), 1.0); } } if (input.pad_buttons_down & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB)) { if (g_Config.bBufferedRendering) fbo_unbind(); screenManager()->push(new PauseScreen()); } }
void LanguageScreen::render() { UIShader_Prepare(); UIBegin(UIShader_Get()); DrawBackground(1.0f); I18NCategory *s = GetI18NCategory("System"); I18NCategory *g = GetI18NCategory("General"); I18NCategory *l = GetI18NCategory("Language"); ui_draw2d.SetFontScale(1.5f, 1.5f); ui_draw2d.DrawText(UBUNTU24, s->T("Language"), dp_xres / 2, 20, 0xFFFFFFFF, ALIGN_HCENTER); ui_draw2d.SetFontScale(1.0f, 1.0f); if (UIButton(GEN_ID, Pos(dp_xres - 10, dp_yres-10), LARGE_BUTTON_WIDTH, 0, g->T("Back"), ALIGN_RIGHT | ALIGN_BOTTOM)) { screenManager()->finishDialog(this, DR_OK); } VGrid vlang(50, 100, dp_yres - 50, 10, 10); std::string text; for (size_t i = 0; i < langs_.size(); i++) { std::string code; size_t dot = langs_[i].name.find('.'); if (dot != std::string::npos) code = langs_[i].name.substr(0, dot); std::string buttonTitle = langs_[i].name; langValuesMapping["ja_JP"] = std::make_pair("日本語", PSP_SYSTEMPARAM_LANGUAGE_JAPANESE); langValuesMapping["en_US"] = std::make_pair("English",PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["fr_FR"] = std::make_pair("Français", PSP_SYSTEMPARAM_LANGUAGE_FRENCH); langValuesMapping["es_ES"] = std::make_pair("Español", PSP_SYSTEMPARAM_LANGUAGE_SPANISH); langValuesMapping["es_LA"] = std::make_pair("Español", PSP_SYSTEMPARAM_LANGUAGE_SPANISH); langValuesMapping["de_DE"] = std::make_pair("Deutsch", PSP_SYSTEMPARAM_LANGUAGE_GERMAN); langValuesMapping["it_IT"] = std::make_pair("Italiano", PSP_SYSTEMPARAM_LANGUAGE_ITALIAN); langValuesMapping["nl_NL"] = std::make_pair("Nederlands", PSP_SYSTEMPARAM_LANGUAGE_DUTCH); langValuesMapping["pt_PT"] = std::make_pair("Português", PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE); langValuesMapping["pt_BR"] = std::make_pair("Português", PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE); langValuesMapping["ru_RU"] = std::make_pair("Русский", PSP_SYSTEMPARAM_LANGUAGE_RUSSIAN); langValuesMapping["ko_KR"] = std::make_pair("한국어", PSP_SYSTEMPARAM_LANGUAGE_KOREAN); langValuesMapping["zh_TW"] = std::make_pair("繁體中文", PSP_SYSTEMPARAM_LANGUAGE_CHINESE_TRADITIONAL); langValuesMapping["zh_CN"] = std::make_pair("简体中文", PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED); langValuesMapping["gr_EL"] = std::make_pair("ελληνικά", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["he_IL"] = std::make_pair("עברית", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["hu_HU"] = std::make_pair("Magyar", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["pl_PL"] = std::make_pair("Polski", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["sv_SE"] = std::make_pair("Svenska", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["tr_TR"] = std::make_pair("Türk", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["ca_ES"] = std::make_pair("Català", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["uk_UA"] = std::make_pair("Українська", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); langValuesMapping["ro_RO"] = std::make_pair("Român", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); if (!code.empty()) { if(langValuesMapping.find(code) == langValuesMapping.end()) { //No title found, show locale code buttonTitle = code; } else { buttonTitle = langValuesMapping[code].first; } } if (UIButton(GEN_ID_LOOP(i), vlang, LARGE_BUTTON_WIDTH - 30, 0, buttonTitle.c_str(), ALIGN_TOPLEFT)) { std::string oldLang = g_Config.languageIni; g_Config.languageIni = code; if (i18nrepo.LoadIni(g_Config.languageIni)) { // Dunno what else to do here. if(langValuesMapping.find(code) == langValuesMapping.end()) { //Fallback to English g_Config.ilanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; } else { g_Config.ilanguage = langValuesMapping[code].second; } // After this, g and s are no longer valid. Let's return, some flicker is okay. g = GetI18NCategory("General"); s = GetI18NCategory("System"); l = GetI18NCategory("Language"); } else { g_Config.languageIni = oldLang; } } } UIEnd(); }
void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) { if (result == DR_OK) { screenManager()->switchScreen(new MenuScreen()); } }
void SettingsScreen::update(InputState &input) { if (input.pad_buttons_down & PAD_BUTTON_BACK) { g_Config.Save(); screenManager()->switchScreen(new MenuScreen()); } }
UI::EventReturn EmuScreen::OnDevTools(UI::EventParams ¶ms) { screenManager()->push(new DevMenu()); return UI::EVENT_DONE; }
void MenuScreen::render() { UIShader_Prepare(); UIBegin(); DrawBackground(1.0f); double xoff = 150 - frames_ * frames_ * 0.4f; if (xoff < -20) xoff = -20; if (frames_ > 200) // seems the above goes nuts after a while... xoff = -20; int w = LARGE_BUTTON_WIDTH + 40; ui_draw2d.DrawTextShadow(UBUNTU48, "PPSSPP", dp_xres + xoff - w/2, 80, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_BOTTOM); ui_draw2d.SetFontScale(0.7f, 0.7f); ui_draw2d.DrawTextShadow(UBUNTU24, PPSSPP_GIT_VERSION, dp_xres + xoff, 80, 0xFFFFFFFF, ALIGN_RIGHT | ALIGN_BOTTOM); ui_draw2d.SetFontScale(1.0f, 1.0f); VLinear vlinear(dp_xres + xoff, 95, 20); if (UIButton(GEN_ID, vlinear, w, "Load...", ALIGN_RIGHT)) { #if defined(USING_QT_UI) QString fileName = QFileDialog::getOpenFileName(NULL, "Load ROM", g_Config.currentDirectory.c_str(), "PSP ROMs (*.iso *.cso *.pbp *.elf)"); if (QFile::exists(fileName)) { QDir newPath; g_Config.currentDirectory = newPath.filePath(fileName).toStdString(); g_Config.Save(); screenManager()->switchScreen(new EmuScreen(fileName.toStdString())); } #else FileSelectScreenOptions options; options.allowChooseDirectory = true; options.filter = "iso:cso:pbp:elf:prx:"; options.folderIcon = I_ICON_FOLDER; options.iconMapping["iso"] = I_ICON_UMD; options.iconMapping["cso"] = I_ICON_UMD; options.iconMapping["pbp"] = I_ICON_EXE; options.iconMapping["elf"] = I_ICON_EXE; screenManager()->switchScreen(new FileSelectScreen(options)); #endif UIReset(); } if (UIButton(GEN_ID, vlinear, w, "Settings", ALIGN_RIGHT)) { screenManager()->push(new SettingsScreen(), 0); UIReset(); } if (UIButton(GEN_ID, vlinear, w, "Credits", ALIGN_RIGHT)) { screenManager()->switchScreen(new CreditsScreen()); UIReset(); } if (UIButton(GEN_ID, vlinear, w, "Exit", ALIGN_RIGHT)) { // TODO: Save when setting changes, rather than when we quit NativeShutdown(); // TODO: Need a more elegant way to quit exit(0); } if (UIButton(GEN_ID, vlinear, w, "www.ppsspp.org", ALIGN_RIGHT)) { LaunchBrowser("http://www.ppsspp.org/"); } DrawWatermark(); UIEnd(); glsl_bind(UIShader_Get()); ui_draw2d.Flush(UIShader_Get()); }
void EmuScreen::render() { if (invalid_) { // It's possible this might be set outside PSP_RunLoopFor(). // In this case, we need to double check it here. checkPowerDown(); return; } if (PSP_CoreParameter().freezeNext) { PSP_CoreParameter().frozen = true; PSP_CoreParameter().freezeNext = false; SaveState::SaveToRam(freezeState_); } else if (PSP_CoreParameter().frozen) { if (CChunkFileReader::ERROR_NONE != SaveState::LoadFromRam(freezeState_)) { ERROR_LOG(HLE, "Failed to load freeze state. Unfreezing."); PSP_CoreParameter().frozen = false; } } // Reapply the graphics state of the PSP ReapplyGfxState(); // We just run the CPU until we get to vblank. This will quickly sync up pretty nicely. // The actual number of cycles doesn't matter so much here as we will break due to CORE_NEXTFRAME, most of the time hopefully... int blockTicks = usToCycles(1000000 / 10); // Run until CORE_NEXTFRAME 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; } checkPowerDown(); if (invalid_) return; bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; if (useBufferedRendering && g_Config.iGPUBackend == GPU_BACKEND_OPENGL) fbo_unbind(); screenManager()->getUIContext()->RebindTexture(); Thin3DContext *thin3d = screenManager()->getThin3DContext(); T3DViewport viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = pixel_xres; viewport.Height = pixel_yres; viewport.MaxDepth = 1.0; viewport.MinDepth = 0.0; thin3d->SetViewports(1, &viewport); glstate.viewport.restore(); thin3d->SetBlendState(thin3d->GetBlendStatePreset(BS_STANDARD_ALPHA)); ui_draw2d.Begin(thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), DBMODE_NORMAL); if (root_) { UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_); root_->Draw(*screenManager()->getUIContext()); } if (!osm.IsEmpty()) { osm.Draw(ui_draw2d, screenManager()->getUIContext()->GetBounds()); } if (g_Config.bShowDebugStats) { char statbuf[4096] = {0}; __DisplayGetDebugStats(statbuf); if (statbuf[4095]) { ELOG("Statbuf too small! :("); } ui_draw2d.SetFontScale(.7f, .7f); ui_draw2d.DrawText(UBUNTU24, statbuf, 11, 11, 0xc0000000, FLAG_DYNAMIC_ASCII); ui_draw2d.DrawText(UBUNTU24, statbuf, 10, 10, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); ui_draw2d.SetFontScale(1.0f, 1.0f); } if (g_Config.iShowFPSCounter) { float vps, fps, actual_fps; __DisplayGetFPS(&vps, &fps, &actual_fps); char fpsbuf[256]; switch (g_Config.iShowFPSCounter) { case 1: sprintf(fpsbuf, "Speed: %0.1f%%", vps / (59.94f / 100.0f)); break; case 2: sprintf(fpsbuf, "FPS: %0.1f", actual_fps); break; case 3: sprintf(fpsbuf, "%0.0f/%0.0f (%0.1f%%)", actual_fps, fps, vps / (59.94f / 100.0f)); break; default: return; } const Bounds &bounds = screenManager()->getUIContext()->GetBounds(); ui_draw2d.SetFontScale(0.7f, 0.7f); ui_draw2d.DrawText(UBUNTU24, fpsbuf, bounds.x2() - 8, 12, 0xc0000000, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); ui_draw2d.DrawText(UBUNTU24, fpsbuf, bounds.x2() - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); ui_draw2d.SetFontScale(1.0f, 1.0f); } ui_draw2d.End(); ui_draw2d.Flush(); // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? #if defined(USING_GLES2) bool hasDiscard = gl_extensions.EXT_discard_framebuffer; // TODO if (hasDiscard) { //const GLenum targets[3] = { GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT }; //glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, targets); } #endif }
void EmuScreen::update(InputState &input) { globalUIState = UISTATE_INGAME; if (errorMessage_.size()) { screenManager()->push(new ErrorScreen( "Error loading file", errorMessage_)); errorMessage_ = ""; return; } if (invalid_) return; // First translate touches into native pad input. // Do this no matter the value of g_Config.bShowTouchControls, some people // like to use invisible controls... UpdateGamepad(input); UpdateInputState(&input); // Then translate pad input into PSP pad input. Also, add in tilt. 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.pad_buttons_down & mapping[i][0]) { __CtrlButtonDown(mapping[i][1]); } if (input.pad_buttons_up & mapping[i][0]) { __CtrlButtonUp(mapping[i][1]); } } float stick_x = input.pad_lstick_x; float stick_y = input.pad_lstick_y; // Apply tilt if (g_Config.bAccelerometerToAnalogHoriz) { // TODO: Deadzone, etc. stick_x += clamp1(curve1(input.acc.y) * 2.0f); stick_x = clamp1(stick_x); } __CtrlSetAnalog(stick_x, stick_y); if (input.pad_buttons & PAD_BUTTON_LEFT_THUMB) { PSP_CoreParameter().unthrottle = true; } else { PSP_CoreParameter().unthrottle = false; } if (input.pad_buttons_down & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB)) { if (g_Config.bBufferedRendering) fbo_unbind(); screenManager()->push(new PauseScreen()); } }