// Copyright (c) 2012- PPSSPP Project. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 2.0 or later versions. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License 2.0 for more details. // A copy of the GPL 2.0 should have been included with the program. // If not, see http://www.gnu.org/licenses/ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #pragma once #include #include #include #include "Common/File/Path.h" #include "Common/Input/KeyCodes.h" #include "Common/UI/Screen.h" #include "Common/UI/UIScreen.h" #include "Common/UI/Tween.h" #include "Core/KeyMap.h" #include "Core/ControlMapper.h" #include "UI/ImDebugger/ImCommand.h" struct AxisInput; class AsyncImageFileView; class ChatMenu; class ImDebugger; struct ImCommand; struct ImGuiContext; class EmuScreen : public UIScreen, protected ControlListener { public: EmuScreen(const Path &filename); ~EmuScreen(); const char *tag() const override { return "Emu"; } void update() override; ScreenRenderFlags render(ScreenRenderMode mode) override; void dialogFinished(const Screen *dialog, DialogResult result) override; void sendMessage(UIMessage message, const char *value) override; void resized() override; ScreenRenderRole renderRole(bool isTop) const override; // Note: Unlike your average boring UIScreen, here we override the Unsync* functions // to get minimal latency and full control. We forward to UIScreen when needed. bool UnsyncTouch(const TouchInput &touch) override; bool UnsyncKey(const KeyInput &key) override; void UnsyncAxis(const AxisInput *axes, size_t count) override; // We also need to do some special handling of queued UI events to handle closing the chat window. bool key(const KeyInput &key) override; void touch(const TouchInput &key) override; void deviceLost() override; void deviceRestored(Draw::DrawContext *draw) override; void SendImDebuggerCommand(const ImCommand &command) { imCmd_ = command; } protected: void darken(); void focusChanged(ScreenFocusChange focusChange) override; ScreenRenderFlags PreRender(ScreenRenderMode mode) override; // ControlListener implementations void OnVKey(VirtKey virtualKeyCode, bool down) override; void OnVKeyAnalog(VirtKey virtualKeyCode, float value) override; void UpdatePSPButtons(uint32_t buttonMask, uint32_t changedMask) override; void SetPSPAnalog(int rotation, int stick, float x, float y) override; ViewLayoutMode LayoutMode() const override; private: void CreateViews() override; ScreenRenderFlags RunEmulation(bool skipBufferEffects); void OnDevTools(UI::EventParams ¶ms); void OpenChat(bool focus); void HandleFlip(); void ProcessGameBoot(const Path &filename); bool bootAllowStorage(const Path &filename); void bootComplete(); bool hasVisibleUI(); void renderUI(); void runImDebugger(); void renderImDebugger(); void AutoLoadSaveState(); bool checkPowerDown(); void ProcessQueuedVKeys(); void ProcessVKey(VirtKey vkey); bool ShouldRunEmulation(ScreenRenderMode mode) const; UI::Event OnDevMenu; bool bootPending_ = true; bool bootIsReset_ = false; Path gamePath_; bool quit_ = false; std::string errorMessage_; // If set, pauses at the end of the frame. bool pauseTrigger_ = false; // The last read chat message count, and how many new ones there are. int chatMessages_ = 0; int newChatMessages_ = 0; // In-memory save state used for freezeFrame, which is useful for debugging. std::vector freezeState_; std::string tag_; double saveStatePreviewShownTime_ = 0.0; AsyncImageFileView *saveStatePreview_ = nullptr; int saveStateSlot_; UI::CallbackColorTween *loadingViewColor_ = nullptr; UI::VisibilityTween *loadingViewVisible_ = nullptr; UI::Spinner *loadingSpinner_ = nullptr; UI::Button *resumeButton_ = nullptr; UI::Button *resetButton_ = nullptr; UI::Button *backButton_ = nullptr; UI::Clickable *chatButton_ = nullptr; ChatMenu *chatMenu_ = nullptr; UI::Button *cardboardDisableButton_ = nullptr; std::string extraAssertInfoStr_; std::unique_ptr imDebugger_; ImCommand imCmd_{}; // needed to buffer commands in case imgui wasn't created yet. bool imguiInited_ = false; // For ImGui modifier tracking bool keyCtrlLeft_ = false; bool keyCtrlRight_ = false; bool keyShiftLeft_ = false; bool keyShiftRight_ = false; bool keyAltLeft_ = false; bool keyAltRight_ = false; bool lastImguiEnabled_ = false; std::vector queuedVirtKeys_; ImGuiContext *ctx_ = nullptr; bool frameStep_ = false; #ifndef MOBILE_DEVICE bool startDumping_ = false; #endif bool autoLoadFailed_ = false; // to prevent repeat reloads bool readyToFinishBoot_ = false; bool skipBufferEffects_ = false; // cached state, fetched once per frame. uint32_t clearColor_ = 0; }; bool MustRunBehind(); bool ShouldRunBehind();