Files
ppsspp/UI/EmuScreen.h
T
Henrik Rydgård e80c67df25 Fix check for top screen. Fixes a problem with input focus after game reset.
Reported by Flide, thanks!

However, there's some underlying bug in screen focus tracking, this just works around it by checking for top screen in a more reliable way.
2026-03-01 17:47:46 +01:00

174 lines
5.0 KiB
C++

// 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 <list>
#include <string>
#include <vector>
#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/ImDebugger.h"
struct AxisInput;
class AsyncImageFileView;
class ChatMenu;
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;
private:
void CreateViews() override;
ScreenRenderFlags RunEmulation(bool skipBufferEffects);
void OnDevTools(UI::EventParams &params);
void OnChat(UI::EventParams &params);
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;
UI::Event OnChatMenu;
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<u8> 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::View *chatButton_ = nullptr;
ChatMenu *chatMenu_ = nullptr;
UI::Button *cardboardDisableButton_ = nullptr;
std::string extraAssertInfoStr_;
std::unique_ptr<ImDebugger> imDebugger_ = nullptr;
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<VirtKey> 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();