Added a third video driver option for Qt GUI that uses a QPainter object to render QImages to the viewport. Consolidated video driver interface into a base class so generic object pointer can be used throughout the code to control the viewport.

This commit is contained in:
harry 2023-05-09 22:57:05 -04:00
parent a9f4176f2b
commit 3d6cf7a730
9 changed files with 1012 additions and 216 deletions

View File

@ -549,6 +549,7 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleWindow.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleViewerGL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleViewerSDL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleViewerQWidget.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/InputConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GamePadConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/FamilyKeyboard.cpp

View File

@ -85,8 +85,9 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
driverSelect = new QComboBox();
driverSelect->addItem( tr("OpenGL"), 0 );
driverSelect->addItem( tr("SDL"), 1 );
driverSelect->addItem( tr("OpenGL"), ConsoleViewerBase::VIDEO_DRIVER_OPENGL );
driverSelect->addItem( tr("SDL"), ConsoleViewerBase::VIDEO_DRIVER_SDL );
driverSelect->addItem( tr("QPainter"), ConsoleViewerBase::VIDEO_DRIVER_QPAINTER );
hbox1 = new QHBoxLayout();
@ -232,15 +233,10 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
if ( consoleWindow )
{
if ( consoleWindow->viewport_GL )
if ( consoleWindow->viewport_Interface )
{
autoScaleCbx->setChecked( consoleWindow->viewport_GL->getAutoScaleOpt() );
aspectCbx->setChecked( consoleWindow->viewport_GL->getForceAspectOpt() );
}
else if ( consoleWindow->viewport_SDL )
{
autoScaleCbx->setChecked( consoleWindow->viewport_SDL->getAutoScaleOpt() );
aspectCbx->setChecked( consoleWindow->viewport_SDL->getForceAspectOpt() );
autoScaleCbx->setChecked( consoleWindow->viewport_Interface->getAutoScaleOpt() );
aspectCbx->setChecked( consoleWindow->viewport_Interface->getForceAspectOpt() );
}
}
@ -305,15 +301,10 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
if ( consoleWindow )
{
if ( consoleWindow->viewport_GL )
if ( consoleWindow->viewport_Interface )
{
xScaleBox->setValue( consoleWindow->viewport_GL->getScaleX() );
yScaleBox->setValue( consoleWindow->viewport_GL->getScaleY() );
}
else if ( consoleWindow->viewport_SDL )
{
xScaleBox->setValue( consoleWindow->viewport_SDL->getScaleX() );
yScaleBox->setValue( consoleWindow->viewport_SDL->getScaleY() );
xScaleBox->setValue( consoleWindow->viewport_Interface->getScaleX() );
yScaleBox->setValue( consoleWindow->viewport_Interface->getScaleY() );
}
}
@ -594,13 +585,9 @@ void ConsoleVideoConfDialog_t::updateReadouts(void)
w = consoleWindow->size();
if ( consoleWindow->viewport_GL )
if ( consoleWindow->viewport_Interface )
{
v = consoleWindow->viewport_GL->size();
}
else if ( consoleWindow->viewport_SDL )
{
v = consoleWindow->viewport_SDL->size();
v = consoleWindow->viewport_Interface->size();
}
sprintf( stmp, "%i x %i ", w.width(), w.height() );
@ -726,13 +713,9 @@ void ConsoleVideoConfDialog_t::openGL_linearFilterChanged( int value )
if ( consoleWindow != NULL )
{
if ( consoleWindow->viewport_GL )
if ( consoleWindow->viewport_Interface )
{
consoleWindow->viewport_GL->setLinearFilterEnable( opt );
}
if ( consoleWindow->viewport_SDL )
{
consoleWindow->viewport_SDL->setLinearFilterEnable( opt );
consoleWindow->viewport_Interface->setLinearFilterEnable( opt );
}
}
}
@ -745,13 +728,9 @@ void ConsoleVideoConfDialog_t::autoScaleChanged( int value )
if ( consoleWindow != NULL )
{
if ( consoleWindow->viewport_GL )
if ( consoleWindow->viewport_Interface )
{
consoleWindow->viewport_GL->setAutoScaleOpt( opt );
}
if ( consoleWindow->viewport_SDL )
{
consoleWindow->viewport_SDL->setAutoScaleOpt( opt );
consoleWindow->viewport_Interface->setAutoScaleOpt( opt );
}
}
}
@ -832,9 +811,9 @@ void ConsoleVideoConfDialog_t::vsync_changed( int value )
//consoleWindow->viewport_GL->setVsyncEnable( opt );
consoleWindow->loadVideoDriver( 0, true );
}
if ( consoleWindow->viewport_SDL )
else if ( consoleWindow->viewport_Interface )
{
consoleWindow->viewport_SDL->setVsyncEnable( opt );
consoleWindow->viewport_Interface->setVsyncEnable( opt );
}
}
}
@ -1094,15 +1073,10 @@ QSize ConsoleVideoConfDialog_t::calcNewScreenSize(void)
w = consoleWindow->size();
if ( consoleWindow->viewport_GL )
if ( consoleWindow->viewport_Interface )
{
v = consoleWindow->viewport_GL->size();
aspectRatio = consoleWindow->viewport_GL->getAspectRatio();
}
else if ( consoleWindow->viewport_SDL )
{
v = consoleWindow->viewport_SDL->size();
aspectRatio = consoleWindow->viewport_SDL->getAspectRatio();
v = consoleWindow->viewport_Interface->size();
aspectRatio = consoleWindow->viewport_Interface->getAspectRatio();
}
dw = w.width() - v.width();
@ -1167,21 +1141,13 @@ void ConsoleVideoConfDialog_t::applyChanges( void )
g_config->setOption("SDL.WinSizeX", s.width() );
g_config->setOption("SDL.WinSizeY", s.height() );
if ( consoleWindow->viewport_GL )
if ( consoleWindow->viewport_Interface )
{
consoleWindow->viewport_GL->setLinearFilterEnable( gl_LF_chkBox->isChecked() );
consoleWindow->viewport_GL->setForceAspectOpt( aspectCbx->isChecked() );
consoleWindow->viewport_GL->setAutoScaleOpt( autoScaleCbx->isChecked() );
consoleWindow->viewport_GL->setScaleXY( xscale, yscale );
consoleWindow->viewport_GL->reset();
}
if ( consoleWindow->viewport_SDL )
{
consoleWindow->viewport_SDL->setLinearFilterEnable( gl_LF_chkBox->isChecked() );
consoleWindow->viewport_SDL->setForceAspectOpt( aspectCbx->isChecked() );
consoleWindow->viewport_SDL->setAutoScaleOpt( autoScaleCbx->isChecked() );
consoleWindow->viewport_SDL->setScaleXY( xscale, yscale );
consoleWindow->viewport_SDL->reset();
consoleWindow->viewport_Interface->setLinearFilterEnable( gl_LF_chkBox->isChecked() );
consoleWindow->viewport_Interface->setForceAspectOpt( aspectCbx->isChecked() );
consoleWindow->viewport_Interface->setAutoScaleOpt( autoScaleCbx->isChecked() );
consoleWindow->viewport_Interface->setScaleXY( xscale, yscale );
consoleWindow->viewport_Interface->reset();
}
if ( !consoleWindow->isFullScreen() && !consoleWindow->isMaximized() )

View File

@ -10,7 +10,9 @@
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions
#include "Qt/ConsoleViewerInterface.h"
class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions, public ConsoleViewerBase
{
Q_OBJECT
@ -20,6 +22,8 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions
int init(void);
void reset(void);
void queueRedraw(void){ update(); };
int driver(void){ return VIDEO_DRIVER_OPENGL; };
void transfer2LocalBuffer(void);
@ -41,6 +45,13 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions
void screenChanged(QScreen *scr);
void setBgColor( QColor &c );
void setCursor(const QCursor &c){ QOpenGLWidget::setCursor(c); };
void setCursor( Qt::CursorShape s ){ QOpenGLWidget::setCursor(s); };
QSize size(void){ return QOpenGLWidget::size(); };
QCursor cursor(void){ return QOpenGLWidget::cursor(); };
void setMinimumSize(const QSize &s){ return QOpenGLWidget::setMinimumSize(s); };
void setMaximumSize(const QSize &s){ return QOpenGLWidget::setMaximumSize(s); };
protected:
void initializeGL(void);

View File

@ -0,0 +1,51 @@
// ConsoleViewerInterface.h
//
#pragma once
#include <QColor>
#include <QCursor>
#include <QSize>
class ConsoleViewerBase
{
public:
enum VideoDriver
{
VIDEO_DRIVER_OPENGL = 0,
VIDEO_DRIVER_SDL,
VIDEO_DRIVER_QPAINTER
};
virtual int init(void) = 0;
virtual void reset(void) = 0;
virtual void queueRedraw(void) = 0;
virtual int driver(void) = 0;
virtual void transfer2LocalBuffer(void) = 0;
virtual void setVsyncEnable( bool ena ) = 0;
virtual void setLinearFilterEnable( bool ena ) = 0;
virtual bool getForceAspectOpt(void) = 0;
virtual void setForceAspectOpt( bool val ) = 0;
virtual bool getAutoScaleOpt(void) = 0;
virtual void setAutoScaleOpt( bool val ) = 0;
virtual double getScaleX(void) = 0;
virtual double getScaleY(void) = 0;
virtual void setScaleXY( double xs, double ys ) = 0;
virtual void getNormalizedCursorPos( double &x, double &y ) = 0;
virtual bool getMouseButtonState( unsigned int btn ) = 0;
virtual void setAspectXY( double x, double y ) = 0;
virtual void getAspectXY( double &x, double &y ) = 0;
virtual double getAspectRatio(void) = 0;
virtual void setCursor(const QCursor &c) = 0;
virtual void setCursor( Qt::CursorShape s ) = 0;
virtual void setBgColor( QColor &c ) = 0;
virtual QSize size(void) = 0;
virtual QCursor cursor(void) = 0;
virtual void setMinimumSize(const QSize &) = 0;
virtual void setMaximumSize(const QSize &) = 0;
protected:
};

View File

@ -0,0 +1,509 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2020 mjbudd77
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
// GameViewer.cpp
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//#include <unistd.h>
#include "Qt/nes_shm.h"
#include "Qt/throttle.h"
#include "Qt/fceuWrapper.h"
#include "Qt/ConsoleViewerQWidget.h"
#include "Qt/ConsoleUtilities.h"
#include "Qt/ConsoleWindow.h"
extern unsigned int gui_draw_area_width;
extern unsigned int gui_draw_area_height;
ConsoleViewQWidget_t::ConsoleViewQWidget_t(QWidget *parent)
: QWidget( parent )
{
consoleWin_t *win = qobject_cast <consoleWin_t*>(parent);
printf("Initialing QPainter Video Driver\n");
QPalette pal = palette();
pal.setColor(QPalette::Window, Qt::black);
setAutoFillBackground(true);
setPalette(pal);
bgColor = nullptr;
if ( win )
{
bgColor = win->getVideoBgColorPtr();
bgColor->setRgb( 0, 0, 0 );
}
setMinimumWidth( 256 );
setMinimumHeight( 224 );
setFocusPolicy(Qt::StrongFocus);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
view_width = GL_NES_WIDTH;
view_height = GL_NES_HEIGHT;
sx = sy = 0;
rw = view_width;
rh = view_height;
sdlRendW = 0;
sdlRendH = 0;
xscale = 2.0;
yscale = 2.0;
devPixRatio = 1.0f;
aspectRatio = 1.0f;
aspectX = 1.0f;
aspectY = 1.0f;
vsyncEnabled = false;
mouseButtonMask = 0;
localBufSize = (4 * GL_NES_WIDTH) * (4 * GL_NES_HEIGHT) * sizeof(uint32_t);
localBuf = (uint32_t*)malloc( localBufSize );
if ( localBuf )
{
memset( localBuf, 0, localBufSize );
}
forceAspect = true;
autoScaleEna = true;
linearFilter = false;
if ( g_config )
{
int opt;
g_config->getOption("SDL.OpenGLip", &opt );
linearFilter = (opt) ? true : false;
g_config->getOption ("SDL.AutoScale", &opt);
autoScaleEna = (opt) ? true : false;
g_config->getOption("SDL.XScale", &xscale);
g_config->getOption("SDL.YScale", &yscale);
g_config->getOption ("SDL.ForceAspect", &forceAspect);
if ( bgColor )
{
fceuLoadConfigColor( "SDL.VideoBgColor", bgColor );
}
g_config->getOption ("SDL.VideoVsync", &vsyncEnabled);
}
}
ConsoleViewQWidget_t::~ConsoleViewQWidget_t(void)
{
if ( localBuf )
{
free( localBuf ); localBuf = nullptr;
}
cleanup();
}
void ConsoleViewQWidget_t::setBgColor( QColor &c )
{
if ( bgColor )
{
*bgColor = c;
}
}
void ConsoleViewQWidget_t::setVsyncEnable( bool ena )
{
if ( vsyncEnabled != ena )
{
vsyncEnabled = ena;
reset();
}
}
void ConsoleViewQWidget_t::setLinearFilterEnable( bool ena )
{
if ( ena != linearFilter )
{
linearFilter = ena;
reset();
}
}
void ConsoleViewQWidget_t::setScaleXY( double xs, double ys )
{
xscale = xs;
yscale = ys;
if ( forceAspect )
{
if ( xscale < yscale )
{
yscale = xscale;
}
else
{
xscale = yscale;
}
}
}
void ConsoleViewQWidget_t::setAspectXY( double x, double y )
{
aspectX = x;
aspectY = y;
aspectRatio = aspectY / aspectX;
}
void ConsoleViewQWidget_t::getAspectXY( double &x, double &y )
{
x = aspectX;
y = aspectY;
}
double ConsoleViewQWidget_t::getAspectRatio(void)
{
return aspectRatio;
}
void ConsoleViewQWidget_t::transfer2LocalBuffer(void)
{
int i=0, hq = 0, bufIdx;
int numPixels = nes_shm->video.ncol * nes_shm->video.nrow;
unsigned int cpSize = numPixels * 4;
uint8_t *src, *dest;
bufIdx = nes_shm->pixBufIdx-1;
if ( bufIdx < 0 )
{
bufIdx = NES_VIDEO_BUFLEN-1;
}
if ( cpSize > localBufSize )
{
cpSize = localBufSize;
}
src = (uint8_t*)nes_shm->pixbuf[bufIdx];
dest = (uint8_t*)localBuf;
hq = (nes_shm->video.preScaler == 1) || (nes_shm->video.preScaler == 4); // hq2x and hq3x
if ( hq )
{
for (i=0; i<numPixels; i++)
{
dest[3] = 0xFF;
dest[1] = src[1];
dest[2] = src[2];
dest[0] = src[0];
src += 4; dest += 4;
}
}
else
{
memcpy( localBuf, src, cpSize );
}
}
int ConsoleViewQWidget_t::init(void)
{
if ( linearFilter )
{
//SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" );
}
else
{
//SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "0" );
}
return 0;
}
void ConsoleViewQWidget_t::cleanup(void)
{
}
void ConsoleViewQWidget_t::reset(void)
{
cleanup();
if ( init() == 0 )
{
}
else
{
cleanup();
}
}
void ConsoleViewQWidget_t::setCursor(const QCursor &c)
{
QWidget::setCursor(c);
}
void ConsoleViewQWidget_t::setCursor( Qt::CursorShape s )
{
QWidget::setCursor(s);
}
void ConsoleViewQWidget_t::showEvent(QShowEvent *event)
{
//printf("SDL Show: %i x %i \n", width(), height() );
//view_width = width();
//view_height = height();
//gui_draw_area_width = view_width;
//gui_draw_area_height = view_height;
//reset();
}
void ConsoleViewQWidget_t::resizeEvent(QResizeEvent *event)
{
QSize s;
s = event->size();
view_width = s.width();
view_height = s.height();
printf("QWidget Resize: %i x %i \n", view_width, view_height);
gui_draw_area_width = view_width;
gui_draw_area_height = view_height;
reset();
}
void ConsoleViewQWidget_t::mousePressEvent(QMouseEvent * event)
{
//printf("Mouse Button Press: (%i,%i) %x %x\n",
// event->pos().x(), event->pos().y(), event->button(), event->buttons() );
mouseButtonMask = event->buttons();
}
void ConsoleViewQWidget_t::mouseReleaseEvent(QMouseEvent * event)
{
//printf("Mouse Button Release: (%i,%i) %x %x\n",
// event->pos().x(), event->pos().y(), event->button(), event->buttons() );
mouseButtonMask = event->buttons();
}
bool ConsoleViewQWidget_t::getMouseButtonState( unsigned int btn )
{
bool isPressed = false;
if ( mouseButtonMask & btn )
{
isPressed = true;
}
else
{ // Check SDL mouse state just in case SDL is intercepting
// mouse events from window system causing Qt not to see them.
int x, y;
uint32_t b;
b = SDL_GetMouseState( &x, &y);
if ( btn & Qt::LeftButton )
{
if ( b & SDL_BUTTON(SDL_BUTTON_LEFT) )
{
isPressed = true;
}
}
if ( btn & Qt::RightButton )
{
if ( b & SDL_BUTTON(SDL_BUTTON_RIGHT) )
{
isPressed = true;
}
}
if ( btn & Qt::MiddleButton )
{
if ( b & SDL_BUTTON(SDL_BUTTON_MIDDLE) )
{
isPressed = true;
}
}
}
return isPressed;
}
void ConsoleViewQWidget_t::getNormalizedCursorPos( double &x, double &y )
{
QPoint cursor;
cursor = QCursor::pos();
//printf("Global Cursor (%i,%i) \n", cursor.x(), cursor.y() );
cursor = mapFromGlobal( cursor );
//printf("Window Cursor (%i,%i) \n", cursor.x(), cursor.y() );
x = (double)(cursor.x() - sx) / (double)rw;
y = (double)(cursor.y() - sy) / (double)rh;
if ( x < 0.0 )
{
x = 0.0;
}
else if ( x > 1.0 )
{
x = 1.0;
}
if ( y < 0.0 )
{
y = 0.0;
}
else if ( y > 1.0 )
{
y = 1.0;
}
//printf("Normalized Cursor (%f,%f) \n", x, y );
}
void ConsoleViewQWidget_t::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
int nesWidth = GL_NES_WIDTH;
int nesHeight = GL_NES_HEIGHT;
float ixScale = 1.0;
float iyScale = 1.0;
if ( nes_shm != nullptr )
{
nesWidth = nes_shm->video.ncol;
nesHeight = nes_shm->video.nrow;
ixScale = (float)nes_shm->video.xscale;
iyScale = (float)nes_shm->video.yscale;
}
//printf(" %i x %i \n", nesWidth, nesHeight );
float xscaleTmp = (float)view_width / (float)nesWidth;
float yscaleTmp = (float)view_height / (float)nesHeight;
xscaleTmp *= ixScale;
yscaleTmp *= iyScale;
if ( forceAspect )
{
if ( xscaleTmp < yscaleTmp )
{
yscaleTmp = xscaleTmp;
}
else
{
xscaleTmp = yscaleTmp;
}
}
if ( autoScaleEna )
{
xscale = xscaleTmp;
yscale = yscaleTmp;
}
else
{
if ( xscaleTmp > xscale )
{
xscaleTmp = xscale;
}
if ( yscaleTmp > yscale )
{
yscaleTmp = yscale;
}
}
rw=(int)(nesWidth*xscaleTmp/ixScale);
rh=(int)(nesHeight*yscaleTmp/iyScale);
if ( forceAspect )
{
int iw, ih, ax, ay;
ax = (int)(aspectX+0.50);
ay = (int)(aspectY+0.50);
iw = rw * ay;
ih = rh * ax;
if ( iw > ih )
{
rh = (rw * ay) / ax;
}
else
{
rw = (rh * ax) / ay;
}
if ( rw > view_width )
{
rw = view_width;
rh = (rw * ay) / ax;
}
if ( rh > view_height )
{
rh = view_height;
rw = (rh * ax) / ay;
}
}
if ( rw > view_width ) rw = view_width;
if ( rh > view_height) rh = view_height;
sx=(view_width-rw)/2;
sy=(view_height-rh)/2;
if ( bgColor )
{
painter.fillRect( 0, 0, view_width, view_height, *bgColor );
}
else
{
painter.fillRect( 0, 0, view_width, view_height, Qt::black );
}
int rowPitch = nesWidth * sizeof(uint32_t);
QImage tmpImage( (const uchar*)localBuf, nesWidth, nesHeight, rowPitch, QImage::Format_RGB32);
//SDL_Rect source = {0, 0, nesWidth, nesHeight };
QRect dest( sx, sy, rw, rh );
painter.drawImage( dest, tmpImage );
videoBufferSwapMark();
nes_shm->render_count++;
}

View File

@ -0,0 +1,92 @@
// ConsoleViewerQWidget.h
//
#pragma once
#include <QWidget>
#include <QColor>
#include <QCursor>
#include <QImage>
#include <QPaintEvent>
#include <QResizeEvent>
#include "Qt/ConsoleViewerInterface.h"
class ConsoleViewQWidget_t : public QWidget, public ConsoleViewerBase
{
Q_OBJECT
public:
ConsoleViewQWidget_t(QWidget *parent = 0);
~ConsoleViewQWidget_t(void);
int init(void);
void reset(void);
void cleanup(void);
void queueRedraw(void){ update(); };
int driver(void){ return VIDEO_DRIVER_QPAINTER; };
void transfer2LocalBuffer(void);
void setVsyncEnable( bool ena );
void setLinearFilterEnable( bool ena );
bool getForceAspectOpt(void){ return forceAspect; };
void setForceAspectOpt( bool val ){ forceAspect = val; return; };
bool getAutoScaleOpt(void){ return autoScaleEna; };
void setAutoScaleOpt( bool val ){ autoScaleEna = val; return; };
double getScaleX(void){ return xscale; };
double getScaleY(void){ return yscale; };
void setScaleXY( double xs, double ys );
void getNormalizedCursorPos( double &x, double &y );
bool getMouseButtonState( unsigned int btn );
void setAspectXY( double x, double y );
void getAspectXY( double &x, double &y );
double getAspectRatio(void);
void setCursor(const QCursor &c);
void setCursor( Qt::CursorShape s );
void setBgColor( QColor &c );
QSize size(void){ return QWidget::size(); };
QCursor cursor(void){ return QWidget::cursor(); };
void setMinimumSize(const QSize &s){ return QWidget::setMinimumSize(s); };
void setMaximumSize(const QSize &s){ return QWidget::setMaximumSize(s); };
protected:
void paintEvent(QPaintEvent *event);
void showEvent(QShowEvent *event);
void resizeEvent(QResizeEvent *event);
void mousePressEvent(QMouseEvent * event);
void mouseReleaseEvent(QMouseEvent * event);
int view_width;
int view_height;
double devPixRatio;
double aspectRatio;
double aspectX;
double aspectY;
double xscale;
double yscale;
int rw;
int rh;
int sx;
int sy;
int sdlRendW;
int sdlRendH;
bool vsyncEnabled;
bool linearFilter;
bool forceAspect;
bool autoScaleEna;
QColor *bgColor;
uint32_t *localBuf;
uint32_t localBufSize;
unsigned int mouseButtonMask;
private slots:
};

View File

@ -10,7 +10,9 @@
#include <QResizeEvent>
#include <SDL.h>
class ConsoleViewSDL_t : public QWidget
#include "Qt/ConsoleViewerInterface.h"
class ConsoleViewSDL_t : public QWidget, public ConsoleViewerBase
{
Q_OBJECT
@ -22,6 +24,8 @@ class ConsoleViewSDL_t : public QWidget
void reset(void);
void cleanup(void);
void render(void);
void queueRedraw(void){ render(); };
int driver(void){ return VIDEO_DRIVER_SDL; };
void transfer2LocalBuffer(void);
@ -44,6 +48,12 @@ class ConsoleViewSDL_t : public QWidget
void setCursor(const QCursor &c);
void setCursor( Qt::CursorShape s );
void setBgColor( QColor &c );
QSize size(void){ return QWidget::size(); };
QCursor cursor(void){ return QWidget::cursor(); };
void setMinimumSize(const QSize &s){ return QWidget::setMinimumSize(s); };
void setMaximumSize(const QSize &s){ return QWidget::setMaximumSize(s); };
protected:
//void paintEvent(QPaintEvent *event);

View File

@ -113,7 +113,7 @@ consoleWin_t::consoleWin_t(QWidget *parent)
: QMainWindow( parent )
{
int opt, xWinPos = -1, yWinPos = -1, xWinSize = 256, yWinSize = 240;
int use_SDL_video = false;
int videoDriver = 0;
int setFullScreen = false;
//QString libpath = QLibraryInfo::location(QLibraryInfo::PluginsPath);
@ -132,8 +132,10 @@ consoleWin_t::consoleWin_t(QWidget *parent)
firstResize = true;
closeRequested = false;
errorMsgValid = false;
viewport_GL = NULL;
viewport_SDL = NULL;
viewport_GL = NULL;
viewport_SDL = NULL;
viewport_QWidget = NULL;
viewport_Interface = NULL;
contextMenuEnable = false;
soundUseGlobalFocus = false;
@ -148,19 +150,31 @@ consoleWin_t::consoleWin_t(QWidget *parent)
g_config->getOption( "SDL.AutoHideMenuFullsreen", &autoHideMenuFullscreen );
g_config->getOption( "SDL.ContextMenuEnable", &contextMenuEnable );
g_config->getOption( "SDL.Sound.UseGlobalFocus", &soundUseGlobalFocus );
g_config->getOption ("SDL.VideoDriver", &use_SDL_video);
g_config->getOption ("SDL.VideoDriver", &videoDriver);
if ( use_SDL_video )
if ( videoDriver == 1)
{
viewport_SDL = new ConsoleViewSDL_t(this);
setCentralWidget(viewport_SDL);
viewport_Interface = static_cast<ConsoleViewerBase*>(viewport_SDL);
}
else if ( videoDriver == 2)
{
viewport_QWidget = new ConsoleViewQWidget_t(this);
setCentralWidget(viewport_QWidget);
viewport_Interface = static_cast<ConsoleViewerBase*>(viewport_QWidget);
}
else
{
viewport_GL = new ConsoleViewGL_t(this);
setCentralWidget(viewport_GL);
viewport_Interface = static_cast<ConsoleViewerBase*>(viewport_GL);
}
setViewportAspect();
@ -228,14 +242,18 @@ consoleWin_t::consoleWin_t(QWidget *parent)
// the window is resized appropriately. On the first resize event,
// we will set the minimum viewport size back to 1x values that the
// window can be shrunk by dragging lower corner.
if ( viewport_GL != NULL )
if ( viewport_Interface != NULL )
{
viewport_GL->setMinimumSize( reqSize );
}
else if ( viewport_SDL != NULL )
{
viewport_SDL->setMinimumSize( reqSize );
viewport_Interface->setMinimumSize( reqSize );
}
//if ( viewport_GL != NULL )
//{
// viewport_GL->setMinimumSize( reqSize );
//}
//else if ( viewport_SDL != NULL )
//{
// viewport_SDL->setMinimumSize( reqSize );
//}
//this->resize( reqSize );
}
@ -336,6 +354,10 @@ consoleWin_t::~consoleWin_t(void)
{
delete viewport_SDL; viewport_SDL = NULL;
}
if ( viewport_QWidget != NULL )
{
delete viewport_QWidget; viewport_QWidget = NULL;
}
delete mutex;
// LoadGame() checks for an IP and if it finds one begins a network session
@ -368,27 +390,44 @@ int consoleWin_t::videoInit(void)
{
int ret = 0;
if ( viewport_SDL )
if (viewport_Interface)
{
ret = viewport_SDL->init();
}
else if ( viewport_GL )
{
ret = viewport_GL->init();
ret = viewport_Interface->init();
}
//if ( viewport_SDL )
//{
// ret = viewport_SDL->init();
//}
//else if ( viewport_GL )
//{
// ret = viewport_GL->init();
//}
//else if ( viewport_QWidget )
//{
// ret = viewport_QWidget->init();
//}
return ret;
}
void consoleWin_t::videoReset(void)
{
if ( viewport_SDL )
if (viewport_Interface)
{
viewport_SDL->reset();
}
else if ( viewport_GL )
{
viewport_GL->reset();
viewport_Interface->reset();
}
//if ( viewport_SDL )
//{
// viewport_SDL->reset();
//}
//else if ( viewport_GL )
//{
// viewport_GL->reset();
//}
//else if ( viewport_QWidget )
//{
// viewport_QWidget->reset();
//}
return;
}
@ -490,23 +529,40 @@ QSize consoleWin_t::calcRequiredSize(void)
w = size();
if ( viewport_GL )
if ( viewport_Interface )
{
v = viewport_GL->size();
forceAspect = viewport_GL->getForceAspectOpt();
aspectRatio = viewport_GL->getAspectRatio();
xscale = viewport_GL->getScaleX();
yscale = viewport_GL->getScaleY();
}
else if ( viewport_SDL )
{
v = viewport_SDL->size();
forceAspect = viewport_SDL->getForceAspectOpt();
aspectRatio = viewport_SDL->getAspectRatio();
xscale = viewport_SDL->getScaleX();
yscale = viewport_SDL->getScaleY();
v = viewport_Interface->size();
forceAspect = viewport_Interface->getForceAspectOpt();
aspectRatio = viewport_Interface->getAspectRatio();
xscale = viewport_Interface->getScaleX();
yscale = viewport_Interface->getScaleY();
}
//if ( viewport_GL )
//{
// v = viewport_GL->size();
// forceAspect = viewport_GL->getForceAspectOpt();
// aspectRatio = viewport_GL->getAspectRatio();
// xscale = viewport_GL->getScaleX();
// yscale = viewport_GL->getScaleY();
//}
//else if ( viewport_SDL )
//{
// v = viewport_SDL->size();
// forceAspect = viewport_SDL->getForceAspectOpt();
// aspectRatio = viewport_SDL->getAspectRatio();
// xscale = viewport_SDL->getScaleX();
// yscale = viewport_SDL->getScaleY();
//}
//else if ( viewport_QWidget )
//{
// v = viewport_QWidget->size();
// forceAspect = viewport_QWidget->getForceAspectOpt();
// aspectRatio = viewport_QWidget->getAspectRatio();
// xscale = viewport_QWidget->getScaleX();
// yscale = viewport_QWidget->getScaleY();
//}
dw = 0;
dh = 0;
@ -575,14 +631,22 @@ void consoleWin_t::setViewportAspect(void)
break;
}
if ( viewport_GL )
if (viewport_Interface)
{
viewport_GL->setAspectXY( x, y );
}
else if ( viewport_SDL )
{
viewport_SDL->setAspectXY( x, y );
viewport_Interface->setAspectXY( x, y );
}
//if ( viewport_GL )
//{
// viewport_GL->setAspectXY( x, y );
//}
//else if ( viewport_SDL )
//{
// viewport_SDL->setAspectXY( x, y );
//}
//else if ( viewport_QWidget )
//{
// viewport_QWidget->setAspectXY( x, y );
//}
}
void consoleWin_t::setMenuAccessPauseEnable( bool enable )
@ -651,40 +715,65 @@ void consoleWin_t::loadCursor(void)
void consoleWin_t::setViewerCursor( QCursor s )
{
if ( viewport_GL )
if (viewport_Interface)
{
viewport_GL->setCursor(s);
}
else if ( viewport_SDL )
{
viewport_SDL->setCursor(s);
viewport_Interface->setCursor(s);
}
//if ( viewport_GL )
//{
// viewport_GL->setCursor(s);
//}
//else if ( viewport_SDL )
//{
// viewport_SDL->setCursor(s);
//}
//else if ( viewport_QWidget )
//{
// viewport_QWidget->setCursor(s);
//}
}
void consoleWin_t::setViewerCursor( Qt::CursorShape s )
{
if ( viewport_GL )
if (viewport_Interface)
{
viewport_GL->setCursor(s);
}
else if ( viewport_SDL )
{
viewport_SDL->setCursor(s);
viewport_Interface->setCursor(s);
}
//if ( viewport_GL )
//{
// viewport_GL->setCursor(s);
//}
//else if ( viewport_SDL )
//{
// viewport_SDL->setCursor(s);
//}
//else if ( viewport_QWidget )
//{
// viewport_QWidget->setCursor(s);
//}
}
Qt::CursorShape consoleWin_t::getViewerCursor(void)
{
Qt::CursorShape s = Qt::ArrowCursor;
if ( viewport_GL )
if (viewport_Interface)
{
s = viewport_GL->cursor().shape();
}
else if ( viewport_SDL )
{
s = viewport_SDL->cursor().shape();
s = viewport_Interface->cursor().shape();
}
//if ( viewport_GL )
//{
// s = viewport_GL->cursor().shape();
//}
//else if ( viewport_SDL )
//{
// s = viewport_SDL->cursor().shape();
//}
//else if ( viewport_QWidget )
//{
// s = viewport_QWidget->cursor().shape();
//}
return s;
}
@ -695,14 +784,23 @@ void consoleWin_t::resizeEvent(QResizeEvent *event)
// We are assuming that window has been exposed and all sizing of menu is finished
// Restore minimum sizes to 1x values after first resize event so that
// window is still able to be shrunk by dragging lower corners.
if ( viewport_GL != NULL )
if (viewport_Interface)
{
viewport_GL->setMinimumSize( QSize( 256, 224 ) );
}
else if ( viewport_SDL != NULL )
{
viewport_SDL->setMinimumSize( QSize( 256, 224 ) );
viewport_Interface->setMinimumSize( QSize( 256, 224 ) );
}
//if ( viewport_GL != NULL )
//{
// viewport_GL->setMinimumSize( QSize( 256, 224 ) );
//}
//else if ( viewport_SDL != NULL )
//{
// viewport_SDL->setMinimumSize( QSize( 256, 224 ) );
//}
//else if ( viewport_QWidget != NULL )
//{
// viewport_QWidget->setMinimumSize( QSize( 256, 224 ) );
//}
firstResize = false;
}
//printf("%i x %i \n", event->size().width(), event->size().height() );
@ -2011,83 +2109,101 @@ void consoleWin_t::createMainMenu(void)
//---------------------------------------------------------------------------
int consoleWin_t::loadVideoDriver( int driverId, bool force )
{
if ( driverId )
{ // SDL Driver
if ( viewport_SDL != NULL )
if (viewport_Interface)
{
if (viewport_Interface->driver() == driverId)
{ // Already Loaded
if ( force )
if (force)
{
if ( viewport_SDL == centralWidget() )
switch (viewport_Interface->driver())
{
takeCentralWidget();
}
delete viewport_SDL;
case ConsoleViewerBase::VIDEO_DRIVER_OPENGL:
{
if ( viewport_GL == centralWidget() )
{
takeCentralWidget();
}
delete viewport_GL;
viewport_GL = NULL;
}
break;
case ConsoleViewerBase::VIDEO_DRIVER_SDL:
{
if ( viewport_SDL == centralWidget() )
{
takeCentralWidget();
}
delete viewport_SDL;
viewport_SDL = NULL;
}
break;
case ConsoleViewerBase::VIDEO_DRIVER_QPAINTER:
{
if ( viewport_QWidget == centralWidget() )
{
takeCentralWidget();
}
delete viewport_QWidget;
viewport_QWidget = NULL;
}
break;
default:
printf("Error: Invalid video driver\n");
break;
}
viewport_SDL = NULL;
}
else
{
return 0;
}
}
if ( viewport_GL != NULL )
{
if ( viewport_GL == centralWidget() )
{
takeCentralWidget();
}
delete viewport_GL;
viewport_GL = NULL;
}
viewport_SDL = new ConsoleViewSDL_t(this);
setCentralWidget(viewport_SDL);
setViewportAspect();
viewport_SDL->init();
}
else
{ // OpenGL Driver
if ( viewport_GL != NULL )
{ // Already Loaded
if ( force )
{
if ( viewport_GL == centralWidget() )
{
takeCentralWidget();
}
delete viewport_GL;
viewport_GL = NULL;
}
else
{
return 0;
}
}
if ( viewport_SDL != NULL )
switch ( driverId )
{
case ConsoleViewerBase::VIDEO_DRIVER_SDL:
{
if ( viewport_SDL == centralWidget() )
{
takeCentralWidget();
}
delete viewport_SDL;
viewport_SDL = new ConsoleViewSDL_t(this);
viewport_SDL = NULL;
viewport_Interface = static_cast<ConsoleViewerBase*>(viewport_SDL);
setCentralWidget(viewport_SDL);
setViewportAspect();
viewport_SDL->init();
}
viewport_GL = new ConsoleViewGL_t(this);
break;
case ConsoleViewerBase::VIDEO_DRIVER_OPENGL:
{
viewport_GL = new ConsoleViewGL_t(this);
setCentralWidget(viewport_GL);
viewport_Interface = static_cast<ConsoleViewerBase*>(viewport_GL);
setViewportAspect();
setCentralWidget(viewport_GL);
viewport_GL->init();
setViewportAspect();
viewport_GL->init();
}
break;
case ConsoleViewerBase::VIDEO_DRIVER_QPAINTER:
{
viewport_QWidget = new ConsoleViewQWidget_t(this);
viewport_Interface = static_cast<ConsoleViewerBase*>(viewport_QWidget);
setCentralWidget(viewport_QWidget);
setViewportAspect();
viewport_QWidget->init();
}
break;
}
// Reload Viewport Cursor Type and Visibility
@ -2283,16 +2399,27 @@ void consoleWin_t::videoBgColorChanged( QColor &c )
{
//printf("Color Changed\n");
if ( viewport_GL )
if ( viewport_Interface )
{
viewport_GL->setBgColor(c);
viewport_GL->update();
}
else if ( viewport_SDL )
{
viewport_SDL->setBgColor(c);
viewport_SDL->render();
viewport_Interface->setBgColor(c);
viewport_Interface->queueRedraw();
}
//if ( viewport_GL )
//{
// viewport_GL->setBgColor(c);
// viewport_GL->update();
//}
//else if ( viewport_SDL )
//{
// viewport_SDL->setBgColor(c);
// viewport_SDL->render();
//}
//else if ( viewport_QWidget )
//{
// viewport_QWidget->setBgColor(c);
// viewport_QWidget->update();
//}
}
//---------------------------------------------------------------------------
int consoleWin_t::showListSelectDialog( const char *title, std::vector <std::string> &l )
@ -2899,6 +3026,10 @@ void consoleWin_t::takeScreenShot(void)
{
image = screen->grabWindow( viewport_SDL->winId() );
}
else if ( viewport_QWidget )
{
image = screen->grabWindow( viewport_QWidget->winId() );
}
for (u = 0; u < 99999; ++u)
{
@ -3214,18 +3345,30 @@ void consoleWin_t::winResizeIx(int iscale)
w = size();
if ( viewport_GL )
if ( viewport_Interface )
{
v = viewport_GL->size();
aspectRatio = viewport_GL->getAspectRatio();
forceAspect = viewport_GL->getForceAspectOpt();
}
else if ( viewport_SDL )
{
v = viewport_SDL->size();
aspectRatio = viewport_SDL->getAspectRatio();
forceAspect = viewport_SDL->getForceAspectOpt();
v = viewport_Interface->size();
aspectRatio = viewport_Interface->getAspectRatio();
forceAspect = viewport_Interface->getForceAspectOpt();
}
//if ( viewport_GL )
//{
// v = viewport_GL->size();
// aspectRatio = viewport_GL->getAspectRatio();
// forceAspect = viewport_GL->getForceAspectOpt();
//}
//else if ( viewport_SDL )
//{
// v = viewport_SDL->size();
// aspectRatio = viewport_SDL->getAspectRatio();
// forceAspect = viewport_SDL->getForceAspectOpt();
//}
//else if ( viewport_QWidget )
//{
// v = viewport_QWidget->size();
// aspectRatio = viewport_QWidget->getAspectRatio();
// forceAspect = viewport_QWidget->getForceAspectOpt();
//}
dw = w.width() - v.width();
dh = w.height() - v.height();
@ -4490,16 +4633,26 @@ void consoleWin_t::transferVideoBuffer(void)
{
nes_shm->blitUpdated = 0;
if ( viewport_SDL )
if (viewport_Interface)
{
viewport_SDL->transfer2LocalBuffer();
viewport_SDL->render();
}
else if ( viewport_GL )
{
viewport_GL->transfer2LocalBuffer();
viewport_GL->update();
viewport_Interface->transfer2LocalBuffer();
viewport_Interface->queueRedraw();
}
//if ( viewport_SDL )
//{
// viewport_SDL->transfer2LocalBuffer();
// viewport_SDL->render();
//}
//else if ( viewport_GL )
//{
// viewport_GL->transfer2LocalBuffer();
// viewport_GL->update();
//}
//else if ( viewport_QWidget )
//{
// viewport_QWidget->transfer2LocalBuffer();
// viewport_QWidget->update();
//}
}
}

View File

@ -30,6 +30,7 @@
#include "Qt/ColorMenu.h"
#include "Qt/ConsoleViewerGL.h"
#include "Qt/ConsoleViewerSDL.h"
#include "Qt/ConsoleViewerQWidget.h"
#include "Qt/GamePadConf.h"
#include "Qt/AviRecord.h"
@ -126,8 +127,10 @@ class consoleWin_t : public QMainWindow
consoleWin_t(QWidget *parent = 0);
~consoleWin_t(void);
ConsoleViewGL_t *viewport_GL;
ConsoleViewSDL_t *viewport_SDL;
ConsoleViewGL_t *viewport_GL;
ConsoleViewSDL_t *viewport_SDL;
ConsoleViewQWidget_t *viewport_QWidget;
ConsoleViewerBase *viewport_Interface;
void setCyclePeriodms( int ms );