mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2024-11-14 13:27:41 -07:00
start actually implementing multi-window feature, still rough around the edges
fix crash when closing main window if sub windows are involved fix OpenGL context handling, still need to fix when changing display type
This commit is contained in:
parent
f375099613
commit
881a740cab
@ -199,6 +199,10 @@ void EmuInstance::createWindow()
|
|||||||
numWindows++;
|
numWindows++;
|
||||||
|
|
||||||
emuThread->attachWindow(win);
|
emuThread->attachWindow(win);
|
||||||
|
|
||||||
|
// if creating a secondary window, we may need to initialize its OpenGL context here
|
||||||
|
if (win->hasOpenGL() && (win != topWindow))
|
||||||
|
emuThread->initContext(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuInstance::deleteWindow(int id, bool close)
|
void EmuInstance::deleteWindow(int id, bool close)
|
||||||
@ -208,12 +212,8 @@ void EmuInstance::deleteWindow(int id, bool close)
|
|||||||
MainWindow* win = windowList[id];
|
MainWindow* win = windowList[id];
|
||||||
if (!win) return;
|
if (!win) return;
|
||||||
|
|
||||||
if (win->hasOpenGL() && win == mainWindow)
|
if (win->hasOpenGL())
|
||||||
{
|
emuThread->deinitContext(id);
|
||||||
// we intentionally don't unpause here
|
|
||||||
emuThread->emuPause();
|
|
||||||
emuThread->deinitContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
emuThread->detachWindow(win);
|
emuThread->detachWindow(win);
|
||||||
|
|
||||||
@ -226,9 +226,10 @@ void EmuInstance::deleteWindow(int id, bool close)
|
|||||||
if (close)
|
if (close)
|
||||||
win->close();
|
win->close();
|
||||||
|
|
||||||
if ((!mainWindow) && (!deleting))
|
if (numWindows == 0)
|
||||||
{
|
{
|
||||||
// if we closed this instance's main window, delete the instance
|
// if we closed the last window, delete the instance
|
||||||
|
// if the main window is closed, Qt will take care of closing any secondary windows
|
||||||
deleteEmuInstance(instanceID);
|
deleteEmuInstance(instanceID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,24 +293,18 @@ bool EmuInstance::usesOpenGL()
|
|||||||
(globalCfg.GetInt("3D.Renderer") != renderer3D_Software);
|
(globalCfg.GetInt("3D.Renderer") != renderer3D_Software);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuInstance::initOpenGL()
|
void EmuInstance::initOpenGL(int win)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < kMaxWindows; i++)
|
if (windowList[win])
|
||||||
{
|
windowList[win]->initOpenGL();
|
||||||
if (windowList[i])
|
|
||||||
windowList[i]->initOpenGL();
|
|
||||||
}
|
|
||||||
|
|
||||||
setVSyncGL(true);
|
setVSyncGL(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuInstance::deinitOpenGL()
|
void EmuInstance::deinitOpenGL(int win)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < kMaxWindows; i++)
|
if (windowList[win])
|
||||||
{
|
windowList[win]->deinitOpenGL();
|
||||||
if (windowList[i])
|
|
||||||
windowList[i]->deinitOpenGL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuInstance::setVSyncGL(bool vsync)
|
void EmuInstance::setVSyncGL(bool vsync)
|
||||||
|
@ -103,8 +103,8 @@ public:
|
|||||||
void emuStop(melonDS::Platform::StopReason reason);
|
void emuStop(melonDS::Platform::StopReason reason);
|
||||||
|
|
||||||
bool usesOpenGL();
|
bool usesOpenGL();
|
||||||
void initOpenGL();
|
void initOpenGL(int win);
|
||||||
void deinitOpenGL();
|
void deinitOpenGL(int win);
|
||||||
void setVSyncGL(bool vsync);
|
void setVSyncGL(bool vsync);
|
||||||
void makeCurrentGL();
|
void makeCurrentGL();
|
||||||
void drawScreenGL();
|
void drawScreenGL();
|
||||||
|
@ -115,7 +115,7 @@ void EmuThread::run()
|
|||||||
|
|
||||||
if (emuInstance->usesOpenGL())
|
if (emuInstance->usesOpenGL())
|
||||||
{
|
{
|
||||||
emuInstance->initOpenGL();
|
emuInstance->initOpenGL(0);
|
||||||
|
|
||||||
useOpenGL = true;
|
useOpenGL = true;
|
||||||
videoRenderer = globalCfg.GetInt("3D.Renderer");
|
videoRenderer = globalCfg.GetInt("3D.Renderer");
|
||||||
@ -547,12 +547,12 @@ void EmuThread::handleMessages()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case msg_InitGL:
|
case msg_InitGL:
|
||||||
emuInstance->initOpenGL();
|
emuInstance->initOpenGL(msg.param.value<int>());
|
||||||
useOpenGL = true;
|
useOpenGL = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case msg_DeInitGL:
|
case msg_DeInitGL:
|
||||||
emuInstance->deinitOpenGL();
|
emuInstance->deinitOpenGL(msg.param.value<int>());
|
||||||
useOpenGL = false;
|
useOpenGL = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -650,15 +650,15 @@ void EmuThread::changeWindowTitle(char* title)
|
|||||||
emit windowTitleChange(QString(title));
|
emit windowTitleChange(QString(title));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::initContext()
|
void EmuThread::initContext(int win)
|
||||||
{
|
{
|
||||||
sendMessage(msg_InitGL);
|
sendMessage({.type = msg_InitGL, .param = win});
|
||||||
waitMessage();
|
waitMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::deinitContext()
|
void EmuThread::deinitContext(int win)
|
||||||
{
|
{
|
||||||
sendMessage(msg_DeInitGL);
|
sendMessage({.type = msg_DeInitGL, .param = win});
|
||||||
waitMessage();
|
waitMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,8 +127,8 @@ public:
|
|||||||
bool emuIsRunning();
|
bool emuIsRunning();
|
||||||
bool emuIsActive();
|
bool emuIsActive();
|
||||||
|
|
||||||
void initContext();
|
void initContext(int win);
|
||||||
void deinitContext();
|
void deinitContext(int win);
|
||||||
void updateVideoSettings() { videoSettingsDirty = true; }
|
void updateVideoSettings() { videoSettingsDirty = true; }
|
||||||
void updateVideoRenderer() { videoSettingsDirty = true; lastVideoRenderer = -1; }
|
void updateVideoRenderer() { videoSettingsDirty = true; lastVideoRenderer = -1; }
|
||||||
|
|
||||||
|
@ -736,6 +736,8 @@ ScreenPanelGL::ScreenPanelGL(QWidget* parent) : ScreenPanel(parent)
|
|||||||
setAttribute(Qt::WA_KeyCompression, false);
|
setAttribute(Qt::WA_KeyCompression, false);
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
setMinimumSize(screenGetMinSize());
|
setMinimumSize(screenGetMinSize());
|
||||||
|
|
||||||
|
glInited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenPanelGL::~ScreenPanelGL()
|
ScreenPanelGL::~ScreenPanelGL()
|
||||||
@ -781,6 +783,7 @@ void ScreenPanelGL::setSwapInterval(int intv)
|
|||||||
void ScreenPanelGL::initOpenGL()
|
void ScreenPanelGL::initOpenGL()
|
||||||
{
|
{
|
||||||
if (!glContext) return;
|
if (!glContext) return;
|
||||||
|
if (glInited) return;
|
||||||
|
|
||||||
glContext->MakeCurrent();
|
glContext->MakeCurrent();
|
||||||
|
|
||||||
@ -877,11 +880,13 @@ void ScreenPanelGL::initOpenGL()
|
|||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0));
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0));
|
||||||
|
|
||||||
transferLayout();
|
transferLayout();
|
||||||
|
glInited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenPanelGL::deinitOpenGL()
|
void ScreenPanelGL::deinitOpenGL()
|
||||||
{
|
{
|
||||||
if (!glContext) return;
|
if (!glContext) return;
|
||||||
|
if (!glInited) return;
|
||||||
|
|
||||||
glDeleteTextures(1, &screenTexture);
|
glDeleteTextures(1, &screenTexture);
|
||||||
|
|
||||||
@ -906,6 +911,7 @@ void ScreenPanelGL::deinitOpenGL()
|
|||||||
glContext->DoneCurrent();
|
glContext->DoneCurrent();
|
||||||
|
|
||||||
lastScreenWidth = lastScreenHeight = -1;
|
lastScreenWidth = lastScreenHeight = -1;
|
||||||
|
glInited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenPanelGL::makeCurrentGL()
|
void ScreenPanelGL::makeCurrentGL()
|
||||||
|
@ -197,6 +197,7 @@ private:
|
|||||||
void setupScreenLayout() override;
|
void setupScreenLayout() override;
|
||||||
|
|
||||||
std::unique_ptr<GL::Context> glContext;
|
std::unique_ptr<GL::Context> glContext;
|
||||||
|
bool glInited;
|
||||||
|
|
||||||
GLuint screenVertexBuffer, screenVertexArray;
|
GLuint screenVertexBuffer, screenVertexArray;
|
||||||
GLuint screenTexture;
|
GLuint screenTexture;
|
||||||
|
@ -588,6 +588,13 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
menu->addSeparator();
|
||||||
|
|
||||||
|
actNewWindow = menu->addAction("Open new window");
|
||||||
|
connect(actNewWindow, &QAction::triggered, this, &MainWindow::onOpenNewWindow);
|
||||||
|
|
||||||
|
menu->addSeparator();
|
||||||
|
|
||||||
actScreenFiltering = menu->addAction("Screen filtering");
|
actScreenFiltering = menu->addAction("Screen filtering");
|
||||||
actScreenFiltering->setCheckable(true);
|
actScreenFiltering->setCheckable(true);
|
||||||
connect(actScreenFiltering, &QAction::triggered, this, &MainWindow::onChangeScreenFiltering);
|
connect(actScreenFiltering, &QAction::triggered, this, &MainWindow::onChangeScreenFiltering);
|
||||||
@ -1950,6 +1957,11 @@ void MainWindow::onChangeIntegerScaling(bool checked)
|
|||||||
emit screenLayoutChange();
|
emit screenLayoutChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::onOpenNewWindow()
|
||||||
|
{
|
||||||
|
emuInstance->createWindow();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::onChangeScreenFiltering(bool checked)
|
void MainWindow::onChangeScreenFiltering(bool checked)
|
||||||
{
|
{
|
||||||
windowCfg.SetBool("ScreenFilter", checked);
|
windowCfg.SetBool("ScreenFilter", checked);
|
||||||
@ -2077,7 +2089,7 @@ void MainWindow::onUpdateVideoSettings(bool glchange)
|
|||||||
if (glchange)
|
if (glchange)
|
||||||
{
|
{
|
||||||
emuThread->emuPause();
|
emuThread->emuPause();
|
||||||
if (hasOGL) emuThread->deinitContext();
|
if (hasOGL) emuThread->deinitContext(windowID);
|
||||||
|
|
||||||
delete panel;
|
delete panel;
|
||||||
createScreenPanel();
|
createScreenPanel();
|
||||||
@ -2088,7 +2100,7 @@ void MainWindow::onUpdateVideoSettings(bool glchange)
|
|||||||
|
|
||||||
if (glchange)
|
if (glchange)
|
||||||
{
|
{
|
||||||
if (hasOGL) emuThread->initContext();
|
if (hasOGL) emuThread->initContext(windowID);
|
||||||
emuThread->emuUnpause();
|
emuThread->emuUnpause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,6 +208,7 @@ private slots:
|
|||||||
void onChangeScreenSizing(QAction* act);
|
void onChangeScreenSizing(QAction* act);
|
||||||
void onChangeScreenAspect(QAction* act);
|
void onChangeScreenAspect(QAction* act);
|
||||||
void onChangeIntegerScaling(bool checked);
|
void onChangeIntegerScaling(bool checked);
|
||||||
|
void onOpenNewWindow();
|
||||||
void onChangeScreenFiltering(bool checked);
|
void onChangeScreenFiltering(bool checked);
|
||||||
void onChangeShowOSD(bool checked);
|
void onChangeShowOSD(bool checked);
|
||||||
void onChangeLimitFramerate(bool checked);
|
void onChangeLimitFramerate(bool checked);
|
||||||
@ -325,6 +326,7 @@ public:
|
|||||||
QAction** actScreenAspectTop;
|
QAction** actScreenAspectTop;
|
||||||
QActionGroup* grpScreenAspectBot;
|
QActionGroup* grpScreenAspectBot;
|
||||||
QAction** actScreenAspectBot;
|
QAction** actScreenAspectBot;
|
||||||
|
QAction* actNewWindow;
|
||||||
QAction* actScreenFiltering;
|
QAction* actScreenFiltering;
|
||||||
QAction* actShowOSD;
|
QAction* actShowOSD;
|
||||||
QAction* actLimitFramerate;
|
QAction* actLimitFramerate;
|
||||||
|
Loading…
Reference in New Issue
Block a user