From 53dcb48a90555c559b93b2e7bca8c0d69d44cddd Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 29 Jun 2020 10:11:02 -0400 Subject: [PATCH] Successful test of SDL video driver inside QT window. --- fceux.pro | 2 + src/drivers/Qt/GameApp.cpp | 6 +- src/drivers/Qt/GameApp.h | 5 +- src/drivers/Qt/GameViewerSDL.cpp | 151 +++++++++++++++++++++++++++++++ src/drivers/Qt/GameViewerSDL.h | 37 ++++++++ src/drivers/Qt/main.cpp | 2 + src/drivers/Qt/sdl-video.cpp | 4 +- 7 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 src/drivers/Qt/GameViewerSDL.cpp create mode 100644 src/drivers/Qt/GameViewerSDL.h diff --git a/fceux.pro b/fceux.pro index 93ad5b28..46a7c2fd 100644 --- a/fceux.pro +++ b/fceux.pro @@ -294,10 +294,12 @@ SOURCES += src/drivers/common/nes_ntsc.c HEADERS += src/drivers/Qt/GameApp.h HEADERS += src/drivers/Qt/GameViewerGL.h +HEADERS += src/drivers/Qt/GameViewerSDL.h HEADERS += src/drivers/Qt/GamePadConf.h SOURCES += src/drivers/Qt/main.cpp SOURCES += src/drivers/Qt/GameApp.cpp SOURCES += src/drivers/Qt/GameViewerGL.cpp +SOURCES += src/drivers/Qt/GameViewerSDL.cpp SOURCES += src/drivers/Qt/GamePadConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp SOURCES += src/drivers/Qt/config.cpp diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 274a4507..0a799a95 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -19,7 +19,8 @@ gameWin_t::gameWin_t(QWidget *parent) createMainMenu(); - viewport = new gameViewGL_t(); + //viewport = new gameViewGL_t(this); + viewport = new gameViewSDL_t(this); //viewport.resize( 200, 200 ); layout->addWidget(viewport); @@ -234,7 +235,8 @@ void gameWin_t::runGameFrame(void) fceuWrapperUpdate(); - viewport->repaint(); + //viewport->repaint(); + viewport->update(); return; } diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index d2500b82..98f72fe4 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -16,6 +16,7 @@ #include #include "Qt/GameViewerGL.h" +#include "Qt/GameViewerSDL.h" #include "Qt/GamePadConf.h" class gameWin_t : public QMainWindow @@ -26,8 +27,10 @@ class gameWin_t : public QMainWindow gameWin_t(QWidget *parent = 0); ~gameWin_t(void); - gameViewGL_t *viewport; + //gameViewGL_t *viewport; + gameViewSDL_t *viewport; + protected: QMenu *fileMenu; QMenu *optMenu; QMenu *helpMenu; diff --git a/src/drivers/Qt/GameViewerSDL.cpp b/src/drivers/Qt/GameViewerSDL.cpp new file mode 100644 index 00000000..7ec04b81 --- /dev/null +++ b/src/drivers/Qt/GameViewerSDL.cpp @@ -0,0 +1,151 @@ +// GameViewer.cpp +// +#include +#include +#include +#include +#include + +#include "Qt/gl_win.h" +#include "Qt/GameViewerSDL.h" + +extern unsigned int gui_draw_area_width; +extern unsigned int gui_draw_area_height; + +gameViewSDL_t::gameViewSDL_t(QWidget *parent) + : QWidget( parent ) +{ + view_width = GL_NES_WIDTH; + view_height = GL_NES_HEIGHT; + + sdlWindow = NULL; + sdlRenderer = NULL; + sdlTexture = NULL; + + vsyncEnabled = false; +} + +gameViewSDL_t::~gameViewSDL_t(void) +{ + +} + +int gameViewSDL_t::init(void) +{ + WId windowHandle; + + if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) + { + printf("[SDL] Failed to initialize video subsystem.\n"); + return -1; + } + else + { + printf("Initialized SDL Video Subsystem\n"); + } + + windowHandle = this->winId(); + + printf("Window Handle: %llu \n", windowHandle ); + + //sleep(1); + + sdlWindow = SDL_CreateWindowFrom( (void*)windowHandle); + if (sdlWindow == NULL) + { + printf("[SDL] Failed to create window from handle.\n"); + return -1; + } + + uint32_t baseFlags = vsyncEnabled ? SDL_RENDERER_PRESENTVSYNC : 0; + + sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, baseFlags | SDL_RENDERER_ACCELERATED); + + if (sdlRenderer == NULL) + { + printf("[SDL] Failed to create accelerated renderer.\n"); + + printf("[SDL] Attempting to create software renderer...\n"); + + sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, baseFlags | SDL_RENDERER_SOFTWARE); + + if (sdlRenderer == NULL) + { + printf("[SDL] Failed to create software renderer.\n"); + return -1; + } + } + + sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, GL_NES_WIDTH, GL_NES_HEIGHT); + + if (sdlTexture == NULL) + { + printf("[SDL] Failed to create texture: %i x %i", GL_NES_WIDTH, GL_NES_HEIGHT ); + return -1; + } + + return 0; +} + +void gameViewSDL_t::cleanup(void) +{ + if (sdlTexture) + { + SDL_DestroyTexture(sdlTexture); + sdlTexture = NULL; + } + if (sdlRenderer) + { + SDL_DestroyRenderer(sdlRenderer); + sdlRenderer = NULL; + } +} + +void gameViewSDL_t::reset(void) +{ + cleanup(); + if ( init() == 0 ) + { + //console->GetVideoRenderer()->RegisterRenderingDevice(this); + } + else + { + cleanup(); + } +} + +void gameViewSDL_t::resizeEvent(QResizeEvent *event) +{ + QSize s; + + s = event->size(); + view_width = s.width(); + view_height = s.height(); + printf("SDL Resize: %i x %i \n", view_width, view_height); + reset(); +} + +void gameViewSDL_t::update(void) +{ + if ( (sdlRenderer == NULL) || (sdlTexture == NULL) ) + { + return; + } + + SDL_RenderClear(sdlRenderer); + + uint8_t *textureBuffer; + int rowPitch; + SDL_LockTexture( sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch); + { + memcpy( textureBuffer, gl_shm->pixbuf, GL_NES_HEIGHT*GL_NES_WIDTH*sizeof(uint32_t) ); + } + SDL_UnlockTexture(sdlTexture); + + SDL_Rect source = {0, 0, GL_NES_WIDTH, GL_NES_HEIGHT }; + SDL_Rect dest = {0, 0, view_width, view_height }; + SDL_RenderCopy(sdlRenderer, sdlTexture, &source, &dest); + + SDL_RenderPresent(sdlRenderer); + +} diff --git a/src/drivers/Qt/GameViewerSDL.h b/src/drivers/Qt/GameViewerSDL.h new file mode 100644 index 00000000..1377077d --- /dev/null +++ b/src/drivers/Qt/GameViewerSDL.h @@ -0,0 +1,37 @@ +// GameViewerSDL.h +// + +#pragma once + +#include +#include +#include + +class gameViewSDL_t : public QWidget +{ + Q_OBJECT + + public: + gameViewSDL_t(QWidget *parent = 0); + ~gameViewSDL_t(void); + + int init(void); + void reset(void); + void cleanup(void); + void update(void); + + protected: + + void resizeEvent(QResizeEvent *event); + int view_width; + int view_height; + + bool vsyncEnabled; + + SDL_Window *sdlWindow; + SDL_Renderer *sdlRenderer; + SDL_Texture *sdlTexture; + + private slots: +}; + diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index fc4b9718..4379b0ad 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -13,6 +13,8 @@ int main( int argc, char *argv[] ) win.resize( 512, 512 ); win.show(); + win.viewport->init(); + return app.exec(); } diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index 47afb1f6..4f784aa1 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -184,9 +184,9 @@ int InitVideo(FCEUGI *gi) FCEUI_SetShowFPS(show_fps); #ifdef LSB_FIRST - rmask = 0x000000FF; + rmask = 0x00FF0000; gmask = 0x0000FF00; - bmask = 0x00FF0000; + bmask = 0x000000FF; #else rmask = 0x00FF0000; gmask = 0x0000FF00;