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>
|
2020-01-02 06:13:03 +00:00
|
|
|
#include <QtCore/QObject>
|
|
|
|
#include <QtCore/QSettings>
|
|
|
|
#include <QtCore/QThread>
|
|
|
|
#include <atomic>
|
|
|
|
#include <functional>
|
|
|
|
#include <map>
|
|
|
|
#include <memory>
|
2020-01-24 04:49:49 +00:00
|
|
|
#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
|
|
|
|
2020-01-10 03:28:13 +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();
|
2020-01-24 04:49:49 +00:00
|
|
|
|
|
|
|
/// 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; }
|
|
|
|
|
|
|
|
QWidget* createDisplayWidget(QWidget* parent);
|
2020-01-24 04:49:51 +00:00
|
|
|
bool createDisplayDeviceContext();
|
2020-01-07 08:55:36 +00:00
|
|
|
void displayWidgetDestroyed();
|
2019-12-31 06:17:17 +00:00
|
|
|
|
|
|
|
void bootSystem(QString initial_filename, QString initial_save_state_filename);
|
|
|
|
|
2020-01-02 06:13:03 +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:
|
2020-01-24 04:51:30 +00:00
|
|
|
void errorReported(QString message);
|
|
|
|
void messageReported(QString message);
|
2019-12-31 06:17:17 +00:00
|
|
|
void emulationStarting();
|
|
|
|
void emulationStarted();
|
|
|
|
void emulationStopped();
|
|
|
|
void emulationPaused(bool paused);
|
|
|
|
void gameListRefreshed();
|
2020-01-06 06:27:39 +00:00
|
|
|
void toggleFullscreenRequested();
|
2020-01-24 04:49:51 +00:00
|
|
|
void recreateDisplayWidgetRequested(bool create_device_context);
|
2020-02-09 13:16:25 +00:00
|
|
|
void systemPerformanceCountersUpdated(float speed, float fps, float vps, float avg_frame_time,
|
|
|
|
float worst_frame_time);
|
2020-01-24 04:50:46 +00:00
|
|
|
void runningGameChanged(QString filename, QString game_code, QString game_title);
|
2019-12-31 06:17:17 +00:00
|
|
|
|
|
|
|
public Q_SLOTS:
|
2020-01-24 04:49:49 +00:00
|
|
|
void applySettings();
|
2020-01-24 04:50:54 +00:00
|
|
|
void powerOffSystem(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();
|
2020-01-02 06:13:03 +00:00
|
|
|
void doBootSystem(QString initial_filename, QString initial_save_state_filename);
|
|
|
|
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
|
|
|
|
2020-01-24 04:49:47 +00:00
|
|
|
protected:
|
2020-01-24 04:51:52 +00:00
|
|
|
void SwitchGPURenderer() override;
|
2020-02-09 13:16:25 +00:00
|
|
|
void OnSystemPerformanceCountersUpdated() override;
|
2020-01-24 04:51:05 +00:00
|
|
|
void OnRunningGameChanged() override;
|
2020-01-24 04:49:47 +00:00
|
|
|
|
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();
|
2020-01-24 04:49:49 +00:00
|
|
|
void updateQSettingsFromCoreSettings();
|
|
|
|
|
2020-01-05 02:46:03 +00:00
|
|
|
void updateControllerInputMap();
|
|
|
|
void updateHotkeyInputMap();
|
|
|
|
void addButtonToInputMap(const QString& binding, InputButtonHandler handler);
|
2020-01-07 04:17:41 +00:00
|
|
|
void createAudioStream();
|
2019-12-31 06:17:17 +00:00
|
|
|
void createThread();
|
|
|
|
void stopThread();
|
|
|
|
void threadEntryPoint();
|
2020-01-10 03:28:13 +00:00
|
|
|
void wakeThread();
|
2019-12-31 06:17:17 +00:00
|
|
|
|
|
|
|
QSettings m_qsettings;
|
2020-01-24 04:49:49 +00:00
|
|
|
std::mutex m_qsettings_mutex;
|
2019-12-31 06:17:17 +00:00
|
|
|
|
2020-01-02 07:45:25 +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;
|
2020-01-10 03:28:13 +00:00
|
|
|
QEventLoop* m_worker_thread_event_loop = nullptr;
|
2019-12-31 06:17:17 +00:00
|
|
|
|
2020-01-02 06:13:03 +00:00
|
|
|
std::atomic_bool m_shutdown_flag{false};
|
2019-12-31 06:17:17 +00:00
|
|
|
|
2020-01-02 06:13:03 +00:00
|
|
|
// input key maps, todo hotkeys
|
2020-01-05 02:46:03 +00:00
|
|
|
std::map<int, InputButtonHandler> m_keyboard_input_handlers;
|
2020-01-02 06:13:03 +00:00
|
|
|
};
|