Duckstation/src/duckstation-qt/qthostinterface.h

146 lines
4 KiB
C
Raw Normal View History

2019-12-31 06:17:17 +00:00
#pragma once
#include "core/host_interface.h"
#include "opengldisplaywindow.h"
2020-01-07 08:55:36 +00:00
#include <QtCore/QByteArray>
#include <QtCore/QObject>
#include <QtCore/QSettings>
#include <QtCore/QThread>
#include <atomic>
#include <functional>
#include <map>
#include <memory>
#include <mutex>
2020-01-05 02:46:03 +00:00
#include <utility>
2020-01-07 08:55:36 +00:00
#include <vector>
class ByteStream;
2019-12-31 06:17:17 +00:00
class QEventLoop;
2020-02-15 15:14:04 +00:00
class QMenu;
2019-12-31 06:17:17 +00:00
class QWidget;
class GameList;
class QtHostInterface : public QObject, private HostInterface
{
Q_OBJECT
public:
explicit QtHostInterface(QObject* parent = nullptr);
~QtHostInterface();
void ReportError(const char* message) override;
void ReportMessage(const char* message) override;
void setDefaultSettings();
/// Thread-safe QSettings access.
QVariant getSettingValue(const QString& name);
void putSettingValue(const QString& name, const QVariant& value);
void removeSettingValue(const QString& name);
2019-12-31 06:17:17 +00:00
const GameList* getGameList() const { return m_game_list.get(); }
GameList* getGameList() { return m_game_list.get(); }
2020-01-08 03:37:43 +00:00
void refreshGameList(bool invalidate_cache = false, bool invalidate_database = false);
2019-12-31 06:17:17 +00:00
bool isOnWorkerThread() const { return QThread::currentThread() == m_worker_thread; }
QtDisplayWindow* createDisplayWindow();
2019-12-31 06:17:17 +00:00
void updateInputMap();
void handleKeyEvent(int key, bool pressed);
2020-01-05 02:46:03 +00:00
struct HotkeyInfo
{
QString name;
QString display_name;
QString category;
};
std::vector<HotkeyInfo> getHotkeyList() const;
2020-02-15 15:14:04 +00:00
void populateSaveStateMenus(const char* game_code, QMenu* load_menu, QMenu* save_menu);
2019-12-31 06:17:17 +00:00
Q_SIGNALS:
void errorReported(QString message);
void messageReported(QString message);
2019-12-31 06:17:17 +00:00
void emulationStarted();
void emulationStopped();
void emulationPaused(bool paused);
void gameListRefreshed();
void createDisplayWindowRequested(QThread* worker_thread, bool use_debug_device);
void destroyDisplayWindowRequested();
2020-01-06 06:27:39 +00:00
void toggleFullscreenRequested();
void systemPerformanceCountersUpdated(float speed, float fps, float vps, float avg_frame_time,
float worst_frame_time);
void runningGameChanged(QString filename, QString game_code, QString game_title);
2019-12-31 06:17:17 +00:00
public Q_SLOTS:
void applySettings();
void bootSystemFromFile(QString filename);
void bootSystemFromBIOS();
void destroySystem(bool save_resume_state = false, bool block_until_done = false);
2019-12-31 06:17:17 +00:00
void resetSystem();
void pauseSystem(bool paused);
void changeDisc(QString new_disc_filename);
2020-02-15 15:14:04 +00:00
void loadState(QString filename);
void loadState(bool global, qint32 slot);
void saveState(bool global, qint32 slot, bool block_until_done = false);
2019-12-31 06:17:17 +00:00
private Q_SLOTS:
void doStopThread();
void doUpdateInputMap();
void doHandleKeyEvent(int key, bool pressed);
2020-01-02 09:14:16 +00:00
void onDisplayWindowResized(int width, int height);
2019-12-31 06:17:17 +00:00
protected:
bool AcquireHostDisplay() override;
void ReleaseHostDisplay() override;
std::unique_ptr<AudioStream> CreateAudioStream(AudioBackend backend) override;
void OnSystemCreated() override;
void OnSystemPaused(bool paused) override;
void OnSystemDestroyed() override;
void OnSystemPerformanceCountersUpdated() override;
void OnRunningGameChanged() override;
2019-12-31 06:17:17 +00:00
private:
2020-01-05 02:46:03 +00:00
using InputButtonHandler = std::function<void(bool)>;
2019-12-31 06:17:17 +00:00
class Thread : public QThread
{
public:
Thread(QtHostInterface* parent);
~Thread();
protected:
void run() override;
private:
QtHostInterface* m_parent;
};
void checkSettings();
void updateQSettingsFromCoreSettings();
2020-01-05 02:46:03 +00:00
void updateControllerInputMap();
void updateHotkeyInputMap();
void addButtonToInputMap(const QString& binding, InputButtonHandler handler);
2019-12-31 06:17:17 +00:00
void createThread();
void stopThread();
void threadEntryPoint();
void wakeThread();
2019-12-31 06:17:17 +00:00
QSettings m_qsettings;
std::mutex m_qsettings_mutex;
2019-12-31 06:17:17 +00:00
QtDisplayWindow* m_display_window = nullptr;
2019-12-31 06:17:17 +00:00
QThread* m_original_thread = nullptr;
Thread* m_worker_thread = nullptr;
QEventLoop* m_worker_thread_event_loop = nullptr;
2019-12-31 06:17:17 +00:00
std::atomic_bool m_shutdown_flag{false};
2019-12-31 06:17:17 +00:00
// input key maps, todo hotkeys
2020-01-05 02:46:03 +00:00
std::map<int, InputButtonHandler> m_keyboard_input_handlers;
};