[gens-sdl] VBackend: Removed the bpp parameter from the constructor.
authorDavid Korth <gerbilsoft@gerbilsoft.com>
Mon, 7 Sep 2015 16:12:57 +0000 (12:12 -0400)
committerDavid Korth <gerbilsoft@gerbilsoft.com>
Mon, 7 Sep 2015 16:12:57 +0000 (12:12 -0400)
SdlSWBackend:
- Reinitialize the texture if the framebuffer's color depth changes.
  If m_fb is nullptr, the texture won't be initialized. update() won't
  use the texture if m_fb is nullptr.
- Moved internal variables into a private class.

SdlHandler:
- Use SdlGLBackend instead of SdlSWBackend. SdlSWBackend was enabled
  for testing purposes, but I accidentally committed it in
  commit f6343b63e7ecf254ed74cdceaab4004c6e16cff8.
  ([gens-sdl] Make use of the bpp command line parameter.)

12 files changed:
src/gens-sdl/CrazyEffectLoop.cpp
src/gens-sdl/EmuLoop.cpp
src/gens-sdl/GLBackend.cpp
src/gens-sdl/GLBackend.hpp
src/gens-sdl/SdlGLBackend.cpp
src/gens-sdl/SdlGLBackend.hpp
src/gens-sdl/SdlHandler.cpp
src/gens-sdl/SdlHandler.hpp
src/gens-sdl/SdlSWBackend.cpp
src/gens-sdl/SdlSWBackend.hpp
src/gens-sdl/VBackend.cpp
src/gens-sdl/VBackend.hpp

index 60964a9..842ed9e 100644 (file)
@@ -107,7 +107,7 @@ int CrazyEffectLoop::run(const Options *options)
 
        // Initialize the SDL handlers.
        d->sdlHandler = new SdlHandler();
-       if (d->sdlHandler->init_video(options->bpp()) < 0)
+       if (d->sdlHandler->init_video() < 0)
                return EXIT_FAILURE;
        // No audio here.
        //if (d->sdlHandler->init_audio() < 0)
index f69b6c2..d68a4ac 100644 (file)
@@ -587,7 +587,7 @@ int EmuLoop::run(const Options *options)
 
        // Initialize the SDL handlers.
        d->sdlHandler = new SdlHandler();
-       if (d->sdlHandler->init_video(options->bpp()) < 0)
+       if (d->sdlHandler->init_video() < 0)
                return EXIT_FAILURE;
        if (d->sdlHandler->init_audio() < 0)
                return EXIT_FAILURE;
index b7eeef6..cb4073c 100644 (file)
@@ -376,17 +376,13 @@ void GLBackendPrivate::stopShaderEffects(void)
 
 /** GLBackend **/
 
-GLBackend::GLBackend(MdFb::ColorDepth bpp)
-       : super(bpp)
+GLBackend::GLBackend()
+       : super()
        , d(new GLBackendPrivate(this))
        , m_winW(640), m_winH(480)
 {
        // Default window size is 640x480.
        // GL must be initialized by the subclass.
-
-       // TODO: Remove bpp parameter;
-       // update other classes' bpp when the
-       // MdFb's bpp changes?
 }
 
 GLBackend::~GLBackend()
index c42440b..e15a5e0 100644 (file)
@@ -33,7 +33,7 @@ namespace GensSdl {
 class GLBackendPrivate;
 class GLBackend : public VBackend {
        public:
-               GLBackend(LibGens::MdFb::ColorDepth bpp);
+               GLBackend();
                virtual ~GLBackend();
 
        private:
index a05a31f..d8702b1 100644 (file)
@@ -49,8 +49,8 @@ using LibGens::MdFb;
 
 namespace GensSdl {
 
-SdlGLBackend::SdlGLBackend(MdFb::ColorDepth bpp)
-       : super(bpp)
+SdlGLBackend::SdlGLBackend()
+       : super()
        , m_window(nullptr)
        , m_glContext(nullptr)
 {
index e8ba503..ce123f7 100644 (file)
@@ -37,7 +37,7 @@ namespace GensSdl {
 
 class SdlGLBackend : public GLBackend {
        public:
-               SdlGLBackend(LibGens::MdFb::ColorDepth bpp);
+               SdlGLBackend();
                virtual ~SdlGLBackend();
 
        private:
index fa07024..1cb1262 100644 (file)
@@ -61,10 +61,9 @@ SdlHandler::~SdlHandler()
 /**
  * Initialize SDL video.
  * TODO: Parameter for GL rendering.
- * @param bpp Color depth.
  * @return 0 on success; non-zero on error.
  */
-int SdlHandler::init_video(MdFb::ColorDepth bpp)
+int SdlHandler::init_video(void)
 {
        if (m_vBackend) {
                // Video is already initialized.
@@ -82,7 +81,7 @@ int SdlHandler::init_video(MdFb::ColorDepth bpp)
 
        // Initialize the video backend.
        // TODO: Fullscreen; GL vs. SW selection; VSync.
-       m_vBackend = new SdlSWBackend(bpp);
+       m_vBackend = new SdlGLBackend();
        return 0;
 }
 
index ad9c91e..28787cd 100644 (file)
@@ -63,10 +63,9 @@ class SdlHandler {
                /**
                 * Initialize SDL video.
                 * TODO: Parameter for GL rendering.
-                * @param bpp Color depth.
                 * @return 0 on success; non-zero on error.
                 */
-               int init_video(LibGens::MdFb::ColorDepth bpp);
+               int init_video(void);
 
                /**
                 * Shut down SDL video.
index 15d133d..306014f 100644 (file)
@@ -38,14 +38,115 @@ using LibGens::MdFb;
 
 namespace GensSdl {
 
-SdlSWBackend::SdlSWBackend(MdFb::ColorDepth bpp)
-       : super(bpp)
-       , m_window(nullptr)
-       , m_renderer(nullptr)
-       , m_texture(nullptr)
+class SdlSWBackendPrivate
+{
+       public:
+               SdlSWBackendPrivate(SdlSWBackend *q);
+               ~SdlSWBackendPrivate();
+
+       private:
+               friend class SdlSWBackend;
+               SdlSWBackend *const q;
+       private:
+               // Q_DISABLE_COPY() equivalent.
+               // TODO: Add GensSdl-specific version of Q_DISABLE_COPY().
+               SdlSWBackendPrivate(const SdlSWBackendPrivate &);
+               SdlSWBackendPrivate &operator=(const SdlSWBackendPrivate &);
+
+       public:
+               // Screen context.
+               SDL_Window *window;
+               SDL_Renderer *renderer;
+               SDL_Texture *texture;
+
+               // Last color depth.
+               MdFb::ColorDepth lastBpp;
+
+       public:
+               /**
+                * (Re-)Initialize the texture.
+                * If m_fb is set, uses m_fb's color depth.
+                * Otherwise, BPP_32 is used.
+                */
+               void reinitTexture(void);
+};
+
+/** SdlSWBackendPrivate **/
+
+SdlSWBackendPrivate::SdlSWBackendPrivate(SdlSWBackend *q)
+       : q(q)
+       , window(nullptr)
+       , renderer(nullptr)
+       , texture(nullptr)
+       , lastBpp(MdFb::BPP_MAX)
+{
+       // lastBpp is initialized to MdFb::BPP_MAX in order to
+       // ensure that the texture is initialized. If it's set
+       // to MdFb::BPP_32, then the texture wouldn't get
+       // initialized if m_fb was also set to MdFb::BPP_32.
+}
+
+SdlSWBackendPrivate::~SdlSWBackendPrivate()
+{
+       SDL_DestroyTexture(texture);
+       SDL_DestroyRenderer(renderer);
+       SDL_DestroyWindow(window);
+}
+
+/**
+ * (Re-)Initialize the texture.
+ * If m_fb is set, uses m_fb's color depth.
+ * Otherwise, BPP_32 is used.
+ */
+void SdlSWBackendPrivate::reinitTexture(void)
+{
+       if (!q->m_fb) {
+               // No framebuffer. Don't do anything.
+               return;
+       }
+
+       const MdFb::ColorDepth bpp = q->m_fb->bpp();
+       if (lastBpp == bpp) {
+               // Color depth hasn't changed.
+               return;
+       }
+
+       // Determine the SDL texture format.
+       uint32_t format;
+       switch (bpp) {
+               case MdFb::BPP_15:
+                       format = SDL_PIXELFORMAT_RGB555;
+                       break;
+               case MdFb::BPP_16:
+                       format = SDL_PIXELFORMAT_RGB565;
+                       break;
+               case MdFb::BPP_32:
+               default:
+                       format = SDL_PIXELFORMAT_ARGB8888;
+                       break;
+       }
+
+       if (texture) {
+               // Destroy the existing texture.
+               SDL_DestroyTexture(texture);
+       }
+
+       // Create the texture.
+       texture = SDL_CreateTexture(renderer, format,
+                       SDL_TEXTUREACCESS_STREAMING,
+                       320, 240);
+       // Save the last color depth.
+       lastBpp = bpp;
+}
+
+/** SdlSWBackend **/
+
+SdlSWBackend::SdlSWBackend()
+       : super()
+       , d(new SdlSWBackendPrivate(this))
 {
        // Initialize the SDL window.
-       m_window = SDL_CreateWindow("Gens/GS II [SDL]",
+       d->window = SDL_CreateWindow("Gens/GS II [SDL]",
                                SDL_WINDOWPOS_UNDEFINED,
                                SDL_WINDOWPOS_UNDEFINED,
                                320, 240, SDL_WINDOW_RESIZABLE);
@@ -57,7 +158,7 @@ SdlSWBackend::SdlSWBackend(MdFb::ColorDepth bpp)
        if (hIcon) {
                SDL_SysWMinfo info;
                SDL_VERSION(&info.version);
-               if (SDL_GetWindowWMInfo(m_window, &info)) {
+               if (SDL_GetWindowWMInfo(d->window, &info)) {
                        SetClassLongPtr(info.info.win.window, GCL_HICON, (LONG_PTR)hIcon);
                }
        }
@@ -67,42 +168,20 @@ SdlSWBackend::SdlSWBackend(MdFb::ColorDepth bpp)
 
        // Create a renderer.
        // TODO: Parameter for enabling/disabling VSync?
-       m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_PRESENTVSYNC);
+       d->renderer = SDL_CreateRenderer(d->window, -1, SDL_RENDERER_PRESENTVSYNC);
 
        // Clear the screen.
-       SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255);
-       SDL_RenderClear(m_renderer);
-       SDL_RenderPresent(m_renderer);
+       SDL_SetRenderDrawColor(d->renderer, 0, 0, 0, 255);
+       SDL_RenderClear(d->renderer);
+       SDL_RenderPresent(d->renderer);
 
-       // Create a texture.
-       uint32_t format;
-       switch (bpp) {
-               case MdFb::BPP_15:
-                       format = SDL_PIXELFORMAT_RGB555;
-                       break;
-               case MdFb::BPP_16:
-                       format = SDL_PIXELFORMAT_RGB565;
-                       break;
-               case MdFb::BPP_32:
-               default:
-                       format = SDL_PIXELFORMAT_ARGB8888;
-                       break;
-       }
-       m_texture = SDL_CreateTexture(m_renderer, format,
-                       SDL_TEXTUREACCESS_STREAMING,
-                       320, 240);
+       // Initialize the texture.
+       d->reinitTexture();
 }
 
 SdlSWBackend::~SdlSWBackend()
 {
-       if (m_fb) {
-               m_fb->unref();
-               m_fb = nullptr;
-       }
-
-       SDL_DestroyTexture(m_texture);
-       SDL_DestroyRenderer(m_renderer);
-       SDL_DestroyWindow(m_window);
+       delete d;
 }
 
 /**
@@ -112,7 +191,7 @@ SdlSWBackend::~SdlSWBackend()
  */
 void SdlSWBackend::set_window_title(const char *title)
 {
-       SDL_SetWindowTitle(m_window, title);
+       SDL_SetWindowTitle(d->window, title);
 }
 
 /**
@@ -130,6 +209,7 @@ void SdlSWBackend::set_video_source(LibGens::MdFb *fb)
 
        if (fb) {
                m_fb = fb->ref();
+               d->reinitTexture();
        }
 }
 
@@ -145,20 +225,28 @@ void SdlSWBackend::update(bool fb_dirty)
        ((void)fb_dirty);
 
        // Clear the screen before doing anything else.
-       SDL_RenderClear(m_renderer);
+       SDL_RenderClear(d->renderer);
        if (m_fb) {
                // Source surface is available.
-               // TODO: Verify color depth.
-               if (m_bpp == MdFb::BPP_32) {
-                       SDL_UpdateTexture(m_texture, nullptr, m_fb->fb32(), m_fb->pxPitch() * sizeof(uint32_t));
+               const MdFb::ColorDepth bpp = m_fb->bpp();
+               if (bpp != d->lastBpp) {
+                       // Color depth has changed.
+                       d->reinitTexture();
+               }
+
+               // Update the texture.
+               if (bpp == MdFb::BPP_32) {
+                       SDL_UpdateTexture(d->texture, nullptr,
+                               m_fb->fb32(), m_fb->pxPitch() * sizeof(uint32_t));
                } else {
-                       SDL_UpdateTexture(m_texture, nullptr, m_fb->fb16(), m_fb->pxPitch() * sizeof(uint16_t));
+                       SDL_UpdateTexture(d->texture, nullptr,
+                               m_fb->fb16(), m_fb->pxPitch() * sizeof(uint16_t));
                }
-               SDL_RenderCopy(m_renderer, m_texture, nullptr, nullptr);
+               SDL_RenderCopy(d->renderer, d->texture, nullptr, nullptr);
        }
 
        // Update the screen.
-       SDL_RenderPresent(m_renderer);
+       SDL_RenderPresent(d->renderer);
 
        // VBackend is no longer dirty.
        clearDirty();
@@ -186,10 +274,10 @@ void SdlSWBackend::toggle_fullscreen(void)
        m_fullscreen = !m_fullscreen;
        if (m_fullscreen) {
                // Switched to windowed fullscreen.
-               SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
+               SDL_SetWindowFullscreen(d->window, SDL_WINDOW_FULLSCREEN_DESKTOP);
        } else {
                // Switch to windowed mode.
-               SDL_SetWindowFullscreen(m_window, 0);
+               SDL_SetWindowFullscreen(d->window, 0);
        }
 }
 
index 8bc4b6f..ed9d5bd 100644 (file)
@@ -36,13 +36,16 @@ namespace LibGens {
 
 namespace GensSdl {
 
+class SdlSWBackendPrivate;
 class SdlSWBackend : public VBackend {
        public:
-               SdlSWBackend(LibGens::MdFb::ColorDepth bpp);
+               SdlSWBackend();
                virtual ~SdlSWBackend();
 
        private:
                typedef VBackend super;
+               friend class SdlSWBackendPrivate;
+               SdlSWBackendPrivate *const d;
        private:
                // Q_DISABLE_COPY() equivalent.
                // TODO: Add GensSdl-specific version of Q_DISABLE_COPY().
@@ -81,12 +84,6 @@ class SdlSWBackend : public VBackend {
                 * Toggle fullscreen.
                 */
                virtual void toggle_fullscreen(void) final;
-
-       private:
-               // Screen context.
-               SDL_Window *m_window;
-               SDL_Renderer *m_renderer;
-               SDL_Texture *m_texture;
 };
 
 }
index 9128ebe..2166934 100644 (file)
@@ -29,12 +29,11 @@ using LibGens::MdFb;
 
 namespace GensSdl {
 
-VBackend::VBackend(MdFb::ColorDepth bpp)
+VBackend::VBackend()
        : m_dirty(true)
        , m_fullscreen(false)
        , m_fb(nullptr)
        , m_int_fb(nullptr)
-       , m_bpp(bpp)
        , m_stretchMode(STRETCH_H)
        , m_aspectRatioConstraint(true)
        , m_pausedEffect(false)
index a120d9f..b702426 100644 (file)
@@ -50,7 +50,7 @@ namespace GensSdl {
 
 class VBackend {
        public:
-               VBackend(LibGens::MdFb::ColorDepth bpp);
+               VBackend();
                virtual ~VBackend();
 
        private:
@@ -198,9 +198,6 @@ class VBackend {
                // Internal MdFb for effects.
                LibGens::MdFb *m_int_fb;
 
-               // Internal color depth.
-               LibGens::MdFb::ColorDepth m_bpp;
-
                // Dirty flag functions.
                void setDirty(void);
                void clearDirty(void);