| |
| |
| |
|
|
| #pragma once |
|
|
| #include <atomic> |
| #include <condition_variable> |
| #include <memory> |
| #include <mutex> |
| #include <QThread> |
| #include <QWidget> |
| #include "core/core.h" |
| #include "core/frontend/emu_window.h" |
|
|
| class QKeyEvent; |
| class QTouchEvent; |
|
|
| class GRenderWindow; |
|
|
| namespace Core { |
| class System; |
| } |
|
|
| namespace VideoCore { |
| enum class LoadCallbackStage; |
| } |
|
|
| class EmuThread final : public QThread { |
| Q_OBJECT |
|
|
| public: |
| explicit EmuThread(Core::System& system_, Frontend::GraphicsContext& context); |
| ~EmuThread() override; |
|
|
| |
| |
| |
| |
| void run() override; |
|
|
| |
| |
| |
| |
| void ExecStep() { |
| exec_step = true; |
| running_cv.notify_all(); |
| } |
|
|
| |
| |
| |
| |
| |
| void SetRunning(bool running) { |
| std::unique_lock lock{running_mutex}; |
| this->running = running; |
| lock.unlock(); |
| running_cv.notify_all(); |
| } |
|
|
| |
| |
| |
| |
| |
| bool IsRunning() const { |
| return running; |
| } |
|
|
| |
| |
| |
| void RequestStop() { |
| stop_run = true; |
| SetRunning(false); |
| }; |
|
|
| private: |
| bool exec_step = false; |
| bool running = false; |
| std::atomic<bool> stop_run{false}; |
| std::mutex running_mutex; |
| std::condition_variable running_cv; |
|
|
| Core::System& system; |
| Frontend::GraphicsContext& core_context; |
|
|
| signals: |
| |
| |
| |
| |
| |
| |
| |
| void DebugModeEntered(); |
|
|
| |
| |
| |
| |
| |
| |
| |
| void DebugModeLeft(); |
|
|
| void ErrorThrown(Core::System::ResultStatus, std::string); |
|
|
| void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); |
|
|
| void HideLoadingScreen(); |
| }; |
|
|
| class GRenderWindow : public QWidget, public Frontend::EmuWindow { |
| Q_OBJECT |
|
|
| public: |
| GRenderWindow(QWidget* parent, EmuThread* emu_thread, Core::System& system, bool is_secondary); |
| ~GRenderWindow() override; |
|
|
| |
| void MakeCurrent() override; |
| void DoneCurrent() override; |
| void PollEvents() override; |
| std::unique_ptr<Frontend::GraphicsContext> CreateSharedContext() const override; |
|
|
| void BackupGeometry(); |
| void RestoreGeometry(); |
| void restoreGeometry(const QByteArray& geometry); |
| QByteArray saveGeometry(); |
|
|
| qreal windowPixelRatio() const; |
|
|
| void closeEvent(QCloseEvent* event) override; |
|
|
| void resizeEvent(QResizeEvent* event) override; |
|
|
| void keyPressEvent(QKeyEvent* event) override; |
| void keyReleaseEvent(QKeyEvent* event) override; |
|
|
| void mousePressEvent(QMouseEvent* event) override; |
| void mouseMoveEvent(QMouseEvent* event) override; |
| void mouseReleaseEvent(QMouseEvent* event) override; |
|
|
| bool event(QEvent* event) override; |
|
|
| void focusOutEvent(QFocusEvent* event) override; |
| void focusInEvent(QFocusEvent* event) override; |
| bool HasFocus() const { |
| return has_focus; |
| } |
|
|
| bool InitRenderTarget(); |
|
|
| |
| void ReleaseRenderTarget(); |
|
|
| void CaptureScreenshot(u32 res_scale, const QString& screenshot_path); |
|
|
| std::pair<u32, u32> ScaleTouch(const QPointF pos) const; |
|
|
| public slots: |
|
|
| void OnEmulationStarting(EmuThread* emu_thread); |
| void OnEmulationStopping(); |
| void OnFramebufferSizeChanged(); |
|
|
| signals: |
| |
| void Closed(); |
|
|
| |
| |
| |
| void FirstFrameDisplayed(); |
|
|
| |
| void MouseActivity(); |
|
|
| private: |
| void TouchBeginEvent(const QTouchEvent* event); |
| void TouchUpdateEvent(const QTouchEvent* event); |
| void TouchEndEvent(); |
|
|
| void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override; |
|
|
| #ifdef ENABLE_OPENGL |
| bool InitializeOpenGL(); |
| bool LoadOpenGL(); |
| #endif |
| #ifdef ENABLE_VULKAN |
| void InitializeVulkan(); |
| #endif |
| #ifdef ENABLE_SOFTWARE_RENDERER |
| void InitializeSoftware(); |
| #endif |
|
|
| QWidget* child_widget = nullptr; |
|
|
| EmuThread* emu_thread; |
| Core::System& system; |
|
|
| |
| |
| |
| static std::unique_ptr<Frontend::GraphicsContext> main_context; |
|
|
| |
| QImage screenshot_image; |
| QByteArray geometry; |
| bool first_frame = false; |
| bool has_focus = false; |
|
|
| protected: |
| void showEvent(QShowEvent* event) override; |
| }; |
|
|