Lime3DS/src/citra_qt/bootmanager.hxx
Kevin Hartman 221a9b023d Viewport scaling and display density independence
The view is scaled to be as large as possible, without changing the aspect, within the bounds of the window.
On "retina" displays, or other displays where window units != pixels, the view should no longer draw incorrectly.
2014-11-18 13:06:05 +01:00

126 lines
3.1 KiB
C++

#include <QThread>
#include <QGLWidget>
#include <atomic>
#include "common/common.h"
#include "common/emu_window.h"
class GRenderWindow;
class QKeyEvent;
class EmuThread : public QThread
{
Q_OBJECT
public:
/**
* Set image filename
*
* @param filename
* @warning Only call when not running!
*/
void SetFilename(std::string filename);
/**
* Start emulation (on new thread)
*
* @warning Only call when not running!
*/
void run() override;
/**
* Allow the CPU to process a single instruction (if cpu is not running)
*
* @note This function is thread-safe
*/
void ExecStep() { exec_cpu_step = true; }
/**
* Allow the CPU to continue processing instructions without interruption
*
* @note This function is thread-safe
*/
void SetCpuRunning(bool running) { cpu_running = running; }
/**
* Allow the CPU to continue processing instructions without interruption
*
* @note This function is thread-safe
*/
bool IsCpuRunning() { return cpu_running; }
public slots:
/**
* Stop emulation and wait for the thread to finish.
*
* @details: This function will wait a second for the thread to finish; if it hasn't finished until then, we'll terminate() it and wait another second, hoping that it will be terminated by then.
* @note: This function is thread-safe.
*/
void Stop();
private:
friend class GRenderWindow;
EmuThread(GRenderWindow* render_window);
std::string filename;
bool exec_cpu_step;
bool cpu_running;
std::atomic<bool> stop_run;
GRenderWindow* render_window;
signals:
/**
* Emitted when CPU when we've finished processing a single Gekko instruction
*
* @warning This will only be emitted when the CPU is not running (SetCpuRunning(false))
* @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns)
*/
void CPUStepped();
};
class GRenderWindow : public QWidget, public EmuWindow
{
Q_OBJECT
public:
GRenderWindow(QWidget* parent = NULL);
~GRenderWindow();
void closeEvent(QCloseEvent*) override;
// EmuWindow implementation
void SwapBuffers() override;
void MakeCurrent() override;
void DoneCurrent() override;
void PollEvents() override;
void GetFramebufferSize(int* fbWidth, int* fbHeight) override;
void BackupGeometry();
void RestoreGeometry();
void restoreGeometry(const QByteArray& geometry); // overridden
QByteArray saveGeometry(); // overridden
EmuThread& GetEmuThread();
void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;
void ReloadSetKeymaps() override;
public slots:
void moveContext();
private:
QGLWidget* child;
EmuThread emu_thread;
QByteArray geometry;
/// Device id of keyboard for use with KeyMap
int keyboard_id;
};