Qt: Add screen resize

This commit is contained in:
wheremyfoodat 2024-07-23 16:55:31 +03:00
parent 0f80d0af7a
commit 2e5ab26b46
4 changed files with 63 additions and 0 deletions

View file

@ -50,6 +50,7 @@ class MainWindow : public QMainWindow {
PressTouchscreen,
ReleaseTouchscreen,
ReloadUbershader,
SetScreenSize,
};
// Tagged union representing our message queue messages
@ -81,6 +82,11 @@ class MainWindow : public QMainWindow {
u16 x;
u16 y;
} touchscreen;
struct {
u32 width;
u32 height;
} screenSize;
};
};
@ -141,4 +147,6 @@ class MainWindow : public QMainWindow {
void loadLuaScript(const std::string& code);
void reloadShader(const std::string& shader);
void editCheat(u32 handle, const std::vector<uint8_t>& cheat, const std::function<void(u32)>& callback);
void handleScreenResize(u32 width, u32 height);
};

View file

@ -11,11 +11,20 @@ class ScreenWidget : public QWidget {
public:
ScreenWidget(QWidget* parent = nullptr);
void resizeEvent(QResizeEvent* event) override;
// Called by the emulator thread for resizing the actual GL surface, since the emulator thread owns the GL context
void resizeSurface(u32 width, u32 height);
GL::Context* getGLContext() { return glContext.get(); }
// Dimensions of our output surface
u32 surfaceWidth = 0;
u32 surfaceHeight = 0;
WindowInfo windowInfo;
// Cached "previous" dimensions, used when resizing our window
u32 previousWidth = 0;
u32 previousHeight = 0;
private:
std::unique_ptr<GL::Context> glContext = nullptr;

View file

@ -16,6 +16,7 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
// Enable drop events for loading ROMs
setAcceptDrops(true);
resize(800, 240 * 4);
setCentralWidget(&screen);
screen.show();
appRunning = true;
@ -360,6 +361,15 @@ void MainWindow::dispatchMessage(const EmulatorMessage& message) {
emu->getRenderer()->setUbershader(*message.string.str);
delete message.string.str;
break;
case MessageType::SetScreenSize: {
const u32 width = message.screenSize.width;
const u32 height = message.screenSize.height;
emu->setOutputSize(width, height);
screen.resizeSurface(width, height);
break;
}
}
}
@ -482,6 +492,14 @@ void MainWindow::editCheat(u32 handle, const std::vector<uint8_t>& cheat, const
sendMessage(message);
}
void MainWindow::handleScreenResize(u32 width, u32 height) {
EmulatorMessage message{.type = MessageType::SetScreenSize};
message.screenSize.width = width;
message.screenSize.height = height;
sendMessage(message);
}
void MainWindow::initControllers() {
// Make SDL use consistent positional button mapping
SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0");

View file

@ -12,6 +12,7 @@
#include <qpa/qplatformnativeinterface.h>
#endif
#include "panda_qt/main_window.hpp"
#include "panda_qt/screen.hpp"
// OpenGL screen widget, based on https://github.com/stenzek/duckstation/blob/master/src/duckstation-qt/displaywidget.cpp
@ -35,6 +36,31 @@ ScreenWidget::ScreenWidget(QWidget* parent) : QWidget(parent) {
}
}
void ScreenWidget::resizeEvent(QResizeEvent* event) {
previousWidth = surfaceWidth;
previousHeight = surfaceHeight;
QWidget::resizeEvent(event);
// Update surfaceWidth/surfaceHeight following the resize
std::optional<WindowInfo> windowInfo = getWindowInfo();
if (windowInfo) {
this->windowInfo = *windowInfo;
}
// This will call take care of calling resizeSurface from the emulator thread
static_cast<MainWindow*>(parentWidget())->handleScreenResize(surfaceWidth, surfaceHeight);
}
// Note: This will run on the emulator thread, we don't want any Qt calls happening there.
void ScreenWidget::resizeSurface(u32 width, u32 height) {
if (previousWidth != width || previousHeight != height) {
if (glContext) {
glContext->ResizeSurface(width, height);
}
}
}
bool ScreenWidget::createGLContext() {
// List of GL context versions we will try. Anything 4.1+ is good
static constexpr std::array<GL::Context::Version, 6> versionsToTry = {
@ -45,6 +71,8 @@ bool ScreenWidget::createGLContext() {
std::optional<WindowInfo> windowInfo = getWindowInfo();
if (windowInfo.has_value()) {
this->windowInfo = *windowInfo;
glContext = GL::Context::Create(*getWindowInfo(), versionsToTry);
glContext->DoneCurrent();
}