Files
ppsspp/UI/PauseScreen.h
T
Henrik RydgårdandClaude Opus 5.5 7e4127ae69 Pause menu: Don't close on a state load until the state is in place
Loading a state from the pause menu closed it right away, and the game
ran a few frames from where it was (seen and heard) before the state
was applied. Now savestate operations run while the game is paused under
the menu, and the menu closes once the load (or rewind, or load undo) is
done. Rewind snapshots aren't taken while paused.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 20:42:14 +02:00

99 lines
3.1 KiB
C++

// Copyright (c) 2014- 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 <atomic>
#include <functional>
#include <memory>
#include "Common/File/Path.h"
#include "Common/UI/UIScreen.h"
#include "Common/UI/ViewGroup.h"
#include "Core/SaveState.h"
#include "Core/ControlMapper.h"
#include "UI/BaseScreens.h"
#include "UI/Screen.h"
#include "UI/GameInfoCache.h"
class GamePauseScreen : public UIBaseDialogScreen, protected ControlListener {
public:
GamePauseScreen(const Path &filename, bool bootPending);
~GamePauseScreen();
void dialogFinished(const Screen *dialog, DialogResult dr) override;
const char *tag() const override { return "GamePause"; }
InputMode PassInputToMapper() const override {
return InputMode::ImDebuggerToggle;
}
protected:
void CreateViews() override;
void update() override;
UI::Margins RootMargins() const override;
ViewLayoutMode LayoutMode() const override {
return ViewLayoutMode::ApplyInsets;
}
void OnVKey(VirtKey virtualKeyCode, bool down) override;
private:
void CreateSavestateControls(UI::LinearLayout *viewGroup, UI::LinearLayout **extraRow);
void OnGameSettings(UI::EventParams &e);
void OnExit(UI::EventParams &e);
void OnReportFeedback(UI::EventParams &e);
void OnCreateConfig(UI::EventParams &e);
void OnDeleteConfig(UI::EventParams &e);
void OnState(UI::EventParams &e);
void ShowContextMenu(UI::View *menuButton, bool portrait);
void AddExtraOptions(UI::ViewGroup *parent);
void FinishNextFrame(DialogResult finishNextFrameResult);
// Starts a savestate load (or rewind) with the callback it's given, and closes the menu once the
// state is in place. Closing right away would let the game run a few frames first.
void CloseAfterStateLoad(const std::function<void(SaveState::Callback)> &load);
// Set by the load's callback.
std::shared_ptr<std::atomic<bool>> stateLoadDone_;
// hack
std::mutex finishNextFrameMutex_;
bool finishNextFrame_ = false;
DialogResult finishNextFrameResult_ = DR_CANCEL;
UI::Choice *playButton_ = nullptr;
// State change tracking, a bit ugly heh, but works.
bool lastOnline_ = false;
bool lastNetInited_ = false;
bool lastNetInetInited_ = false;
bool lastAdhocServerConnected_ = false;
bool lastDNSConfigLoaded_ = false;
bool bootPending_ = false;
std::string saveStatePrefix_;
double createdTime_ = 0.0;
};
std::string GetConfirmExitMessage();
void ShowMessageAfterSaveStateAction(SaveState::Status status, std::string_view message, std::string_view metadata);