[gens-sdl] EventLoop_p.hpp: New header for EventLoopPrivate.
authorDavid Korth <gerbilsoft@gerbilsoft.com>
Thu, 3 Sep 2015 03:07:21 +0000 (23:07 -0400)
committerDavid Korth <gerbilsoft@gerbilsoft.com>
Thu, 3 Sep 2015 03:07:21 +0000 (23:07 -0400)
Moved EventLoop's protected and private variables into EventLoopPrivate.

Rebased EmuLoopPrivate and CrazyEffectLoopPrivate on EventLoopPrivate.

Added Qt-style d_func() functions to handle private class inheritance.

Moved the OS-specific includes and yield() macro to EventLoop_p.hpp.

EventLoop: Added a vBackend accessor so gens-sdl can print messages
to the Onscreen Display.

src/gens-sdl/CMakeLists.txt
src/gens-sdl/CrazyEffectLoop.cpp
src/gens-sdl/CrazyEffectLoop.hpp
src/gens-sdl/EmuLoop.cpp
src/gens-sdl/EmuLoop.hpp
src/gens-sdl/EventLoop.cpp
src/gens-sdl/EventLoop.hpp
src/gens-sdl/EventLoop_p.hpp [new file with mode: 0644]
src/gens-sdl/gens-sdl.cpp

index 195372a..6667a03 100644 (file)
@@ -51,6 +51,7 @@ SET(gens-sdl_SRCS
 SET(gens-sdl_H
        gens-sdl.hpp
        EventLoop.hpp
+       EventLoop_p.hpp
        EmuLoop.hpp
        CrazyEffectLoop.hpp
        SdlHandler.hpp
index 3aa43af..917a06b 100644 (file)
@@ -42,36 +42,14 @@ using LibGens::MdFb;
 #include "libgens/Effects/CrazyEffect.hpp"
 using LibGens::CrazyEffect;
 
-// OS-specific includes.
-#ifdef _WIN32
-// Windows
-#include <windows.h>
-// Win32 Unicode Translation Layer.
-// Needed for proper Unicode filename support on Windows.
-#include "libcompat/W32U/W32U_mini.h"
-#include "libcompat/W32U/W32U_argv.h"
-#else
-// Linux, Unix, Mac OS X
-#include <unistd.h>
-#endif
-
-// yield(), aka usleep(0) or Sleep(0)
-#ifdef _WIN32
-// Windows
-#define yield() do { Sleep(0); } while (0)
-#define usleep(usec) Sleep((DWORD)((usec) / 1000))
-#else
-// Linux, Unix, Mac OS X
-#define yield() do { usleep(0); } while (0)
-#endif
-
+#include "EventLoop_p.hpp"
 namespace GensSdl {
 
-class CrazyEffectLoopPrivate
+class CrazyEffectLoopPrivate : public EventLoopPrivate
 {
        public:
                CrazyEffectLoopPrivate();
-               ~CrazyEffectLoopPrivate();
+               virtual ~CrazyEffectLoopPrivate();
 
        private:
                // Q_DISABLE_COPY() equivalent.
@@ -103,13 +81,11 @@ CrazyEffectLoopPrivate::~CrazyEffectLoopPrivate()
 /** CrazyEffectLoop **/
 
 CrazyEffectLoop::CrazyEffectLoop()
-       : d(new CrazyEffectLoopPrivate())
+       : EventLoop(new CrazyEffectLoopPrivate())
 { }
 
 CrazyEffectLoop::~CrazyEffectLoop()
-{
-       delete d;
-}
+{ }
 
 /**
  * Run the event loop.
@@ -124,23 +100,24 @@ int CrazyEffectLoop::run(const char *rom_filename)
        // TODO: Move common code back to gens-sdl?
 
        // Initialize the SDL handlers.
-       m_sdlHandler = new SdlHandler();
-       if (m_sdlHandler->init_video() < 0)
+       CrazyEffectLoopPrivate *const d = d_func();
+       d->sdlHandler = new SdlHandler();
+       if (d->sdlHandler->init_video() < 0)
                return EXIT_FAILURE;
        // No audio here.
-       //if (m_sdlHandler->init_audio() < 0)
+       //if (d->sdlHandler->init_audio() < 0)
        //      return EXIT_FAILURE;
-       m_vBackend = m_sdlHandler->vBackend();
+       d->vBackend = d->sdlHandler->vBackend();
 
        // Set the window title.
-       m_sdlHandler->set_window_title("Gens/GS II [SDL]");
+       d->sdlHandler->set_window_title("Gens/GS II [SDL]");
 
        // Check for startup messages.
        checkForStartupMessages();
 
        // Start the frame timer.
        // TODO: Region code?
-       m_clks.reset();
+       d->clks.reset();
 
        // Create the "Crazy" Effect framebuffer.
        // Image size defaults to the full framebuffer,
@@ -148,20 +125,20 @@ int CrazyEffectLoop::run(const char *rom_filename)
        d->crazyFb = new MdFb();
        d->crazyFb->setBpp(MdFb::BPP_32);
        // Set the SDL video source.
-       m_sdlHandler->set_video_source(d->crazyFb);
+       d->sdlHandler->set_video_source(d->crazyFb);
 
        // Create the "Crazy" Effect object.
        d->crazyEffect = new CrazyEffect();
        d->crazyEffect->setColorMask(CrazyEffect::CM_WHITE);
 
        // TODO: Move some more common stuff back to gens-sdl.cpp.
-       m_running = true;
-       while (m_running) {
+       d->running = true;
+       while (d->running) {
                SDL_Event event;
                int ret;
-               if (m_paused.data) {
+               if (d->paused.data) {
                        // Emulation is paused.
-                       if (!m_vBackend->has_osd_messages()) {
+                       if (!d->vBackend->has_osd_messages()) {
                                // No OSD messages.
                                // Wait for an SDL event.
                                ret = SDL_WaitEvent(&event);
@@ -171,9 +148,9 @@ int CrazyEffectLoop::run(const char *rom_filename)
                        }
 
                        // Process OSD messages.
-                       m_vBackend->process_osd_messages();
+                       d->vBackend->process_osd_messages();
                }
-               if (!m_running)
+               if (!d->running)
                        break;
 
                // Poll for SDL events, and wait for the queue
@@ -184,52 +161,52 @@ int CrazyEffectLoop::run(const char *rom_filename)
                        if (ret) {
                                processSdlEvent(&event);
                        }
-               } while (m_running && ret != 0);
-               if (!m_running)
+               } while (d->running && ret != 0);
+               if (!d->running)
                        break;
 
-               if (m_paused.data) {
+               if (d->paused.data) {
                        // Emulation is paused.
                        // Only update video if the VBackend is dirty
                        // or the SDL window has been exposed.
-                       m_sdlHandler->update_video_paused(m_exposed);
+                       d->sdlHandler->update_video_paused(d->exposed);
 
                        // Don't run any frames.
                        continue;
                }
 
                // Clear the 'exposed' flag.
-               m_exposed = false;
+               d->exposed = false;
 
                // New start time.
-               m_clks.new_clk = m_clks.timing.getTime();
+               d->clks.new_clk = d->clks.timing.getTime();
 
                // Update the FPS counter.
-               unsigned int fps_tmp = ((m_clks.new_clk - m_clks.fps_clk) & 0x3FFFFF);
+               unsigned int fps_tmp = ((d->clks.new_clk - d->clks.fps_clk) & 0x3FFFFF);
                if (fps_tmp >= 1000000) {
                        // More than 1 second has passed.
-                       m_clks.fps_clk = m_clks.new_clk;
+                       d->clks.fps_clk = d->clks.new_clk;
                        // FIXME: Just use abs() here.
-                       if (m_clks.frames_old > m_clks.frames) {
-                               m_clks.fps = (m_clks.frames_old - m_clks.frames);
+                       if (d->clks.frames_old > d->clks.frames) {
+                               d->clks.fps = (d->clks.frames_old - d->clks.frames);
                        } else {
-                               m_clks.fps = (m_clks.frames - m_clks.frames_old);
+                               d->clks.fps = (d->clks.frames - d->clks.frames_old);
                        }
-                       m_clks.frames_old = m_clks.frames;
+                       d->clks.frames_old = d->clks.frames;
 
                        // Update the window title.
                        // TODO: Average the FPS over multiple seconds
                        // and/or quarter-seconds.
                        char win_title[256];
-                       snprintf(win_title, sizeof(win_title), "Gens/GS II [SDL] - %u fps", m_clks.fps);
-                       m_sdlHandler->set_window_title(win_title);
+                       snprintf(win_title, sizeof(win_title), "Gens/GS II [SDL] - %u fps", d->clks.fps);
+                       d->sdlHandler->set_window_title(win_title);
                }
 
                // Run the "Crazy" effect.
                // TODO: Use the frameskip code to limit frames?
                d->crazyEffect->run(d->crazyFb);
-               m_sdlHandler->update_video();
-               m_clks.frames++;
+               d->sdlHandler->update_video();
+               d->clks.frames++;
                yield();
                continue;
        }
index 64037cd..f17b147 100644 (file)
@@ -34,8 +34,7 @@ class CrazyEffectLoop : public EventLoop
                virtual ~CrazyEffectLoop();
 
        private:
-               friend class CrazyEffectLoopPrivate;
-               CrazyEffectLoopPrivate *const d;
+               EVENT_LOOP_DECLARE_PRIVATE(CrazyEffectLoop)
        private:
                // Q_DISABLE_COPY() equivalent.
                // TODO: Add GensSdl-specific version of Q_DISABLE_COPY().
index 948bcf1..aea8715 100644 (file)
@@ -64,40 +64,18 @@ using LibGensKeys::KeyManager;
 using LibZomg::ZomgBase;
 using LibZomg::Zomg;
 
-// OS-specific includes.
-#ifdef _WIN32
-// Windows
-#include <windows.h>
-// Win32 Unicode Translation Layer.
-// Needed for proper Unicode filename support on Windows.
-#include "libcompat/W32U/W32U_mini.h"
-#include "libcompat/W32U/W32U_argv.h"
-#else
-// Linux, Unix, Mac OS X
-#include <unistd.h>
-#endif
-
-// yield(), aka usleep(0) or Sleep(0)
-#ifdef _WIN32
-// Windows
-#define yield() do { Sleep(0); } while (0)
-#define usleep(usec) Sleep((DWORD)((usec) / 1000))
-#else
-// Linux, Unix, Mac OS X
-#define yield() do { usleep(0); } while (0)
-#endif
-
 // C++ includes.
 #include <string>
 using std::string;
 
+#include "EventLoop_p.hpp"
 namespace GensSdl {
 
-class EmuLoopPrivate
+class EmuLoopPrivate : public EventLoopPrivate
 {
        public:
                EmuLoopPrivate();
-               ~EmuLoopPrivate();
+               virtual ~EmuLoopPrivate();
 
        private:
                // Q_DISABLE_COPY() equivalent.
@@ -137,7 +115,8 @@ const GensKey_t EmuLoopPrivate::keyMap_pico[] = {
 };
 
 EmuLoopPrivate::EmuLoopPrivate()
-       : rom(nullptr)
+       : EventLoopPrivate()
+       , rom(nullptr)
        , isPico(false)
        , frameskip(true)
        , emuContext(nullptr)
@@ -155,13 +134,11 @@ EmuLoopPrivate::~EmuLoopPrivate()
 /** EmuLoop **/
 
 EmuLoop::EmuLoop()
-       : d(new EmuLoopPrivate())
+       : EventLoop(new EmuLoopPrivate())
 { }
 
 EmuLoop::~EmuLoop()
-{
-       delete d;
-}
+{ }
 
 /**
  * Process an SDL event.
@@ -169,6 +146,7 @@ EmuLoop::~EmuLoop()
  * @return 0 if the event was handled; non-zero if it wasn't.
  */
 int EmuLoop::processSdlEvent(const SDL_Event *event) {
+       EmuLoopPrivate *const d = d_func();
        int ret = 0;
        switch (event->type) {
                case SDL_KEYDOWN:
@@ -181,11 +159,11 @@ int EmuLoop::processSdlEvent(const SDL_Event *event) {
                                        if (event->key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) {
                                                // Hard Reset.
                                                d->emuContext->hardReset();
-                                               m_vBackend->osd_print(1500, "Hard Reset.");
+                                               d->vBackend->osd_print(1500, "Hard Reset.");
                                        } else {
                                                // Soft Reset.
                                                d->emuContext->softReset();
-                                               m_vBackend->osd_print(1500, "Soft Reset.");
+                                               d->vBackend->osd_print(1500, "Soft Reset.");
                                        }
                                        break;
 
@@ -347,6 +325,7 @@ void EmuLoop::doSaveSlot(int saveSlot)
        assert(saveSlot >= 0 && saveSlot <= 9);
        if (saveSlot < 0 || saveSlot > 9)
                return;
+       EmuLoopPrivate *const d = d_func();
        d->saveSlot_selected = saveSlot;
 
        // Metadata variables.
@@ -385,9 +364,9 @@ void EmuLoop::doSaveSlot(int saveSlot)
        }
 
        // Show an OSD message.
-       m_vBackend->osd_printf(1500, "Slot %d [%s]", saveSlot, slot_state.c_str());
+       d->vBackend->osd_printf(1500, "Slot %d [%s]", saveSlot, slot_state.c_str());
        // If img_data.data is nullptr, this will hide the current image.
-       m_vBackend->osd_preview_image(1500, &img_data);
+       d->vBackend->osd_preview_image(1500, &img_data);
        free(img_data.data);
 }
 
@@ -396,6 +375,7 @@ void EmuLoop::doSaveSlot(int saveSlot)
  */
 void EmuLoop::doLoadState(void)
 {
+       EmuLoopPrivate *const d = d_func();
        assert(d->saveSlot_selected >= 0 && d->saveSlot_selected <= 9);
        if (d->saveSlot_selected < 0 || d->saveSlot_selected > 9)
                return;
@@ -404,17 +384,17 @@ void EmuLoop::doLoadState(void)
        int ret = d->emuContext->zomgLoad(filename.c_str());
        if (ret == 0) {
                // State loaded.
-               m_vBackend->osd_printf(1500, "Slot %d loaded.", d->saveSlot_selected);
+               d->vBackend->osd_printf(1500, "Slot %d loaded.", d->saveSlot_selected);
        } else {
                // Error loading state.
                if (ret == -ENOENT) {
                        // File not found.
-                       m_vBackend->osd_printf(1500,
+                       d->vBackend->osd_printf(1500,
                                "Slot %d is empty.",
                                d->saveSlot_selected);
                } else {
                        // Other error.
-                       m_vBackend->osd_printf(1500,
+                       d->vBackend->osd_printf(1500,
                                "Error loading Slot %d:\n* %s",
                                d->saveSlot_selected, strerror(-ret));
                }
@@ -426,6 +406,7 @@ void EmuLoop::doLoadState(void)
  */
 void EmuLoop::doSaveState(void)
 {
+       EmuLoopPrivate *const d = d_func();
        assert(d->saveSlot_selected >= 0 && d->saveSlot_selected <= 9);
        if (d->saveSlot_selected < 0 || d->saveSlot_selected > 9)
                return;
@@ -434,12 +415,12 @@ void EmuLoop::doSaveState(void)
        int ret = d->emuContext->zomgSave(filename.c_str());
        if (ret == 0) {
                // State saved.
-               m_vBackend->osd_printf(1500,
+               d->vBackend->osd_printf(1500,
                                "Slot %d saved.",
                                d->saveSlot_selected);
        } else {
                // Error saving state.
-               m_vBackend->osd_printf(1500,
+               d->vBackend->osd_printf(1500,
                                "Error saving Slot %d:\n* %s",
                                d->saveSlot_selected, strerror(-ret));
        }
@@ -451,10 +432,11 @@ void EmuLoop::doSaveState(void)
 void EmuLoop::doStretchMode(void)
 {
        // Change stretch mode parameters.
-       int stretchMode = (int)m_vBackend->stretchMode();
+       EmuLoopPrivate *const d = d_func();
+       int stretchMode = (int)d->vBackend->stretchMode();
        stretchMode++;
        stretchMode &= 3;
-       m_vBackend->setStretchMode((VBackend::StretchMode_t)stretchMode);
+       d->vBackend->setStretchMode((VBackend::StretchMode_t)stretchMode);
 
        // Show an OSD message.
        const char *stretch;
@@ -474,7 +456,7 @@ void EmuLoop::doStretchMode(void)
                        break;
        }
 
-       m_vBackend->osd_printf(1500, "Stretch Mode set to %s.", stretch);
+       d->vBackend->osd_printf(1500, "Stretch Mode set to %s.", stretch);
 }
 
 /**
@@ -482,12 +464,13 @@ void EmuLoop::doStretchMode(void)
  */
 void EmuLoop::doScreenShot(void)
 {
+       EmuLoopPrivate *const d = d_func();
        int ret = GensSdl::doScreenShot(d->emuContext->m_vdp->MD_Screen, d->rom);
        if (ret >= 0) {
-               m_vBackend->osd_printf(1500,
+               d->vBackend->osd_printf(1500,
                        "Screenshot %d saved.", ret);
        } else {
-               m_vBackend->osd_printf(1500,
+               d->vBackend->osd_printf(1500,
                        "Error saving screenshot:\n* %s", strerror(-ret));
        }
 }
@@ -500,6 +483,7 @@ void EmuLoop::doScreenShot(void)
 int EmuLoop::run(const char *rom_filename)
 {
        // Load the ROM image.
+       EmuLoopPrivate *const d = d_func();
        d->rom = new Rom(rom_filename);
        if (!d->rom->isOpen()) {
                // Error opening the ROM.
@@ -551,15 +535,15 @@ int EmuLoop::run(const char *rom_filename)
        }
 
        // Initialize the SDL handlers.
-       m_sdlHandler = new SdlHandler();
-       if (m_sdlHandler->init_video() < 0)
+       d->sdlHandler = new SdlHandler();
+       if (d->sdlHandler->init_video() < 0)
                return EXIT_FAILURE;
-       if (m_sdlHandler->init_audio() < 0)
+       if (d->sdlHandler->init_audio() < 0)
                return EXIT_FAILURE;
-       m_vBackend = m_sdlHandler->vBackend();
+       d->vBackend = d->sdlHandler->vBackend();
 
        // Set the window title.
-       m_sdlHandler->set_window_title("Gens/GS II [SDL]");
+       d->sdlHandler->set_window_title("Gens/GS II [SDL]");
 
        // Check for startup messages.
        checkForStartupMessages();
@@ -568,7 +552,7 @@ int EmuLoop::run(const char *rom_filename)
        // TODO: Region code?
        bool isPal = false;
        const unsigned int usec_per_frame = (1000000 / (isPal ? 50 : 60));
-       m_clks.reset();
+       d->clks.reset();
 
        // TODO: Close the ROM, or let EmuContext do it?
 
@@ -578,10 +562,10 @@ int EmuLoop::run(const char *rom_filename)
        fb->setBpp(MdFb::BPP_32);
 
        // Set the SDL video source.
-       m_sdlHandler->set_video_source(fb);
+       d->sdlHandler->set_video_source(fb);
 
        // Start audio.
-       m_sdlHandler->pause_audio(false);
+       d->sdlHandler->pause_audio(false);
 
        // Initialize the I/O Manager with a default key layout.
        d->keyManager = new KeyManager();
@@ -599,13 +583,13 @@ int EmuLoop::run(const char *rom_filename)
 
        // TODO: Move some more common stuff back to gens-sdl.cpp.
        uint8_t old_paused = 0;
-       m_running = true;
-       while (m_running) {
+       d->running = true;
+       while (d->running) {
                SDL_Event event;
                int ret;
-               if (m_paused.data) {
+               if (d->paused.data) {
                        // Emulation is paused.
-                       if (!m_vBackend->has_osd_messages()) {
+                       if (!d->vBackend->has_osd_messages()) {
                                // No OSD messages.
                                // Wait for an SDL event.
                                ret = SDL_WaitEvent(&event);
@@ -615,9 +599,9 @@ int EmuLoop::run(const char *rom_filename)
                        }
 
                        // Process OSD messages.
-                       m_vBackend->process_osd_messages();
+                       d->vBackend->process_osd_messages();
                }
-               if (!m_running)
+               if (!d->running)
                        break;
 
                // Poll for SDL events, and wait for the queue
@@ -628,68 +612,68 @@ int EmuLoop::run(const char *rom_filename)
                        if (ret) {
                                processSdlEvent(&event);
                        }
-               } while (m_running && ret != 0);
-               if (!m_running)
+               } while (d->running && ret != 0);
+               if (!d->running)
                        break;
 
                // Check if the 'paused' state was changed.
                // If it was, autosave SRAM/EEPROM.
-               if (old_paused != m_paused.data) {
+               if (old_paused != d->paused.data) {
                        // 'paused' state was changed.
                        // (TODO: Only if paused == true?)
                        d->emuContext->autoSaveData(-1);
-                       old_paused = m_paused.data;
+                       old_paused = d->paused.data;
                }
 
-               if (m_paused.data) {
+               if (d->paused.data) {
                        // Emulation is paused.
                        // Only update video if the VBackend is dirty
                        // or the SDL window has been exposed.
-                       m_sdlHandler->update_video_paused(m_exposed);
+                       d->sdlHandler->update_video_paused(d->exposed);
 
                        // Don't run any frames.
                        continue;
                }
 
                // Clear the 'exposed' flag.
-               m_exposed = false;
+               d->exposed = false;
 
                // New start time.
-               m_clks.new_clk = m_clks.timing.getTime();
+               d->clks.new_clk = d->clks.timing.getTime();
 
                // Update the FPS counter.
-               unsigned int fps_tmp = ((m_clks.new_clk - m_clks.fps_clk) & 0x3FFFFF);
+               unsigned int fps_tmp = ((d->clks.new_clk - d->clks.fps_clk) & 0x3FFFFF);
                if (fps_tmp >= 1000000) {
                        // More than 1 second has passed.
-                       m_clks.fps_clk = m_clks.new_clk;
+                       d->clks.fps_clk = d->clks.new_clk;
                        // FIXME: Just use abs() here.
-                       if (m_clks.frames_old > m_clks.frames) {
-                               m_clks.fps = (m_clks.frames_old - m_clks.frames);
+                       if (d->clks.frames_old > d->clks.frames) {
+                               d->clks.fps = (d->clks.frames_old - d->clks.frames);
                        } else {
-                               m_clks.fps = (m_clks.frames - m_clks.frames_old);
+                               d->clks.fps = (d->clks.frames - d->clks.frames_old);
                        }
-                       m_clks.frames_old = m_clks.frames;
+                       d->clks.frames_old = d->clks.frames;
 
                        // Update the window title.
                        // TODO: Average the FPS over multiple seconds
                        // and/or quarter-seconds.
                        char win_title[256];
-                       snprintf(win_title, sizeof(win_title), "Gens/GS II [SDL] - %u fps", m_clks.fps);
-                       m_sdlHandler->set_window_title(win_title);
+                       snprintf(win_title, sizeof(win_title), "Gens/GS II [SDL] - %u fps", d->clks.fps);
+                       d->sdlHandler->set_window_title(win_title);
                }
 
                // Frameskip.
-               if (m_frameskip) {
+               if (d->frameskip) {
                        // Determine how many frames to run.
-                       m_clks.usec_frameskip += ((m_clks.new_clk - m_clks.old_clk) & 0x3FFFFF); // no more than 4 secs
-                       unsigned int frames_todo = (unsigned int)(m_clks.usec_frameskip / usec_per_frame);
-                       m_clks.usec_frameskip %= usec_per_frame;
-                       m_clks.old_clk = m_clks.new_clk;
+                       d->clks.usec_frameskip += ((d->clks.new_clk - d->clks.old_clk) & 0x3FFFFF); // no more than 4 secs
+                       unsigned int frames_todo = (unsigned int)(d->clks.usec_frameskip / usec_per_frame);
+                       d->clks.usec_frameskip %= usec_per_frame;
+                       d->clks.old_clk = d->clks.new_clk;
 
                        if (frames_todo == 0) {
                                // No frames to do yet.
                                // Wait until the next frame.
-                               uint64_t usec_sleep = (usec_per_frame - m_clks.usec_frameskip);
+                               uint64_t usec_sleep = (usec_per_frame - d->clks.usec_frameskip);
                                if (usec_sleep > 1000) {
                                        // Never sleep for longer than the 50 Hz value
                                        // so events are checked often enough.
@@ -701,10 +685,10 @@ int EmuLoop::run(const char *rom_filename)
 #ifdef _WIN32
                                        // Win32: Use a yield() loop.
                                        // FIXME: Doesn't work properly on VBox/WinXP...
-                                       uint64_t yield_end = m_clks.timing.getTime() + usec_sleep;
+                                       uint64_t yield_end = d->clks.timing.getTime() + usec_sleep;
                                        do {
                                                yield();
-                                       } while (yield_end > m_clks.timing.getTime());
+                                       } while (yield_end > d->clks.timing.getTime());
 #else /* !_WIN32 */
                                        // Linux: Use usleep().
                                        usleep(usec_sleep);
@@ -715,16 +699,16 @@ int EmuLoop::run(const char *rom_filename)
                                for (; frames_todo != 1; frames_todo--) {
                                        // Run a frame without rendering.
                                        d->emuContext->execFrameFast();
-                                       m_sdlHandler->update_audio();
+                                       d->sdlHandler->update_audio();
                                }
                                frames_todo = 0;
 
                                // Run a frame and render it.
                                d->emuContext->execFrame();
-                               m_sdlHandler->update_audio();
-                               m_sdlHandler->update_video();
+                               d->sdlHandler->update_audio();
+                               d->sdlHandler->update_video();
                                // Increment the frame counter.
-                               m_clks.frames++;
+                               d->clks.frames++;
 
                                // Autosave SRAM/EEPROM.
                                // TODO: EmuContext::execFrame() should probably do this itself...
@@ -733,10 +717,10 @@ int EmuLoop::run(const char *rom_filename)
                } else {
                        // Run a frame and render it.
                        d->emuContext->execFrame();
-                       m_sdlHandler->update_audio();
-                       m_sdlHandler->update_video();
+                       d->sdlHandler->update_audio();
+                       d->sdlHandler->update_video();
                        // Increment the frame counter.
-                       m_clks.frames++;
+                       d->clks.frames++;
 
                        // Autosave SRAM/EEPROM.
                        // TODO: EmuContext::execFrame() should probably do this itself...
@@ -763,16 +747,16 @@ int EmuLoop::run(const char *rom_filename)
        d->rom = nullptr;
 
        // Pause audio and wait 50ms for SDL to catch up.
-       m_sdlHandler->pause_audio(true);
+       d->sdlHandler->pause_audio(true);
        usleep(50000);
 
        // NOTE: Deleting sdlHandler can cause crashes on Windows
        // due to the timer callback trying to post the semaphore
        // after it's been deleted.
        // Shut down the SDL functions manually.
-       m_sdlHandler->end_audio();
-       m_sdlHandler->end_video();
-       m_vBackend = nullptr;
+       d->sdlHandler->end_audio();
+       d->sdlHandler->end_video();
+       d->vBackend = nullptr;
 
        // Done running the emulation loop.
        return 0;
index 3d7e7d0..cb55377 100644 (file)
@@ -39,8 +39,7 @@ class EmuLoop : public EventLoop
                virtual ~EmuLoop();
 
        private:
-               friend class EmuLoopPrivate;
-               EmuLoopPrivate *const d;
+               EVENT_LOOP_DECLARE_PRIVATE(EmuLoop)
        private:
                // Q_DISABLE_COPY() equivalent.
                // TODO: Add GensSdl-specific version of Q_DISABLE_COPY().
index cb29a42..3328771 100644 (file)
@@ -40,47 +40,147 @@ using GensSdl::VBackend;
 #include "libgens/Util/MdFb.hpp"
 using LibGens::MdFb;
 
-// OS-specific includes.
-#ifdef _WIN32
-// Windows
-#include <windows.h>
-// Win32 Unicode Translation Layer.
-// Needed for proper Unicode filename support on Windows.
-#include "libcompat/W32U/W32U_mini.h"
-#include "libcompat/W32U/W32U_argv.h"
-#else
-// Linux, Unix, Mac OS X
-#include <unistd.h>
-#endif
-
-// yield(), aka usleep(0) or Sleep(0)
-#ifdef _WIN32
-// Windows
-#define yield() do { Sleep(0); } while (0)
-#define usleep(usec) Sleep((DWORD)((usec) / 1000))
-#else
-// Linux, Unix, Mac OS X
-#define yield() do { usleep(0); } while (0)
-#endif
-
 // C++ includes.
 #include <string>
 using std::string;
 
+#include "EventLoop_p.hpp"
 namespace GensSdl {
 
-EventLoop::EventLoop()
-       : m_running(false)
-       , m_autoPause(false)
-       , m_lastF1time(0)
+/** EventLoopPrivate **/
+
+EventLoopPrivate::EventLoopPrivate()
+       : sdlHandler(nullptr)
+       , vBackend(nullptr)
+       , running(false)
+       , frameskip(true)
+       , autoPause(false)
+       , exposed(false)
+       , lastF1time(0)
+{
+       paused.data = 0;
+}
+
+EventLoopPrivate::~EventLoopPrivate()
+{
+       // TODO: Shut down SDL if it's still running?
+}
+
+/**
+ * Toggle Fast Blur.
+ */
+void EventLoopPrivate::doFastBlur(void)
+{
+       bool fastBlur = !vBackend->fastBlur();
+       vBackend->setFastBlur(fastBlur);
+
+       // Show an OSD message.
+       if (fastBlur) {
+               vBackend->osd_print(1500, "Fast Blur enabled.");
+       } else {
+               vBackend->osd_print(1500, "Fast Blur disabled.");
+       }
+}
+
+/**
+ * Common pause processing function.
+ * Called by doPause() and doAutoPause().
+ */
+void EventLoopPrivate::doPauseProcessing(void)
+{
+       bool manual = paused.manual;
+       bool any = !!paused.data;
+       // TODO: Option to disable the Paused Effect?
+       // When enabled, it's only used for Manual Pause.
+       vBackend->setPausedEffect(manual);
+
+       // Reset the clocks and counters.
+       clks.reset();
+       // Pause audio.
+       sdlHandler->pause_audio(any);
+
+       // Update the window title.
+       if (manual) {
+               sdlHandler->set_window_title("Gens/GS II [SDL] [Paused]");
+       } else {
+               sdlHandler->set_window_title("Gens/GS II [SDL]");
+       }
+}
+
+/**
+ * Pause/unpause emulation.
+ */
+void EventLoopPrivate::doPause(void)
 {
-       m_paused.data = 0;
+       paused.manual = !paused.manual;
+       doPauseProcessing();
+}
+
+/**
+ * Pause/unpause emulation in response to window focus changes.
+ * @param lostFocus True if window lost focus; false if window gained focus.
+ */
+void EventLoopPrivate::doAutoPause(bool lostFocus)
+{
+       paused.focus = lostFocus;
+       doPauseProcessing();
+}
+
+/**
+ * Show the "About" message.
+ */
+void EventLoopPrivate::doAboutMessage(void)
+{
+       // TODO: OSD Gens logo as preview image, but with drop shadow disabled?
+       const uint64_t curTime = clks.timing.getTime();
+       if (lastF1time > 0 && (lastF1time + 5000000 > curTime)) {
+               // Timer hasn't expired.
+               // Don't show the message.
+               return;
+       }
+
+       // Version string.
+       string ver_str;
+       ver_str.reserve(512);
+       ver_str = "Gens/GS II - SDL2 frontend\n";
+       ver_str += "Version " + string(LibGens::version);
+       if (LibGens::version_vcs) {
+               ver_str += " (" + string(LibGens::version_vcs) + ')';
+       }
+       ver_str += '\n';
+       if (LibGens::version_desc) {
+               ver_str += string(LibGens::version_desc) + '\n';
+       }
+#if !defined(GENS_ENABLE_EMULATION)
+       ver_str += "[NO-EMULATION BUILD]\n";
+#endif
+       ver_str += "(c) 2008-2015 by David Korth.";
+
+       // Show a new message.
+       vBackend->osd_print(5000, ver_str.c_str());
+
+       // Save the current time.
+       lastF1time = curTime;
 }
 
+/** EventLoop **/
+
+EventLoop::EventLoop(EventLoopPrivate *d)
+       : d_ptr(d)
+{ }
+
 EventLoop::~EventLoop()
 {
-       // Shut down SDL.
-       // TODO
+       delete d_ptr;
+}
+
+/**
+ * Get the VBackend.
+ * @return VBackend.
+ */
+VBackend *EventLoop::vBackend(void) const
+{
+       return d_ptr->vBackend;
 }
 
 /**
@@ -88,7 +188,8 @@ EventLoop::~EventLoop()
  * @param event SDL event.
  * @return 0 if the event was handled; non-zero if it wasn't.
  */
-int EventLoop::processSdlEvent(const SDL_Event *event) {
+int EventLoop::processSdlEvent(const SDL_Event *event)
+{
        // NOTE: Some keys are processed in specific event loops
        // instead of here because they only apply if a ROM is loaded.
        // gens-qt4 won't make a distinction, since it can run with
@@ -102,7 +203,7 @@ int EventLoop::processSdlEvent(const SDL_Event *event) {
        int ret = 0;
        switch (event->type) {
                case SDL_QUIT:
-                       m_running = false;
+                       d_ptr->running = false;
                        break;
 
                case SDL_KEYDOWN:
@@ -112,7 +213,7 @@ int EventLoop::processSdlEvent(const SDL_Event *event) {
                        switch (event->key.keysym.sym) {
                                case SDLK_ESCAPE:
                                        // Pause emulation.
-                                       doPause();
+                                       d_ptr->doPause();
                                        break;
 
                                case SDLK_RETURN:
@@ -121,7 +222,7 @@ int EventLoop::processSdlEvent(const SDL_Event *event) {
                                            !(event->key.keysym.mod & ~KMOD_ALT))
                                        {
                                                // Alt+Enter. Toggle fullscreen.
-                                               m_sdlHandler->toggle_fullscreen();
+                                               d_ptr->sdlHandler->toggle_fullscreen();
                                        } else {
                                                // Not Alt+Enter.
                                                // We're not handling this event.
@@ -131,17 +232,17 @@ int EventLoop::processSdlEvent(const SDL_Event *event) {
 
                                case SDLK_F1:
                                        // Show the "About" message.
-                                       doAboutMessage();
+                                       d_ptr->doAboutMessage();
                                        break;
 
                                case SDLK_F9:
                                        // Fast Blur.
-                                       doFastBlur();
+                                       d_ptr->doFastBlur();
                                        break;
 
                                case SDLK_F12:
                                        // FIXME: TEMPORARY KEY BINDING for debugging.
-                                       m_vBackend->setAspectRatioConstraint(!m_vBackend->aspectRatioConstraint());
+                                       d_ptr->vBackend->setAspectRatioConstraint(!d_ptr->vBackend->aspectRatioConstraint());
                                        break;
 
                                default:
@@ -155,24 +256,24 @@ int EventLoop::processSdlEvent(const SDL_Event *event) {
                        switch (event->window.event) {
                                case SDL_WINDOWEVENT_RESIZED:
                                        // Resize the video renderer.
-                                       m_sdlHandler->resize_video(event->window.data1, event->window.data2);
+                                       d_ptr->sdlHandler->resize_video(event->window.data1, event->window.data2);
                                        break;
                                case SDL_WINDOWEVENT_EXPOSED:
                                        // Window has been exposed.
                                        // Tell the main loop to update video.
-                                       m_exposed = true;
+                                       d_ptr->exposed = true;
                                        break;
                                case SDL_WINDOWEVENT_FOCUS_LOST:
                                        // If AutoPause is enabled, pause the emulator.
-                                       if (m_autoPause) {
-                                               doAutoPause(true);
+                                       if (d_ptr->autoPause) {
+                                               d_ptr->doAutoPause(true);
                                        }
                                        break;
                                case SDL_WINDOWEVENT_FOCUS_GAINED:
                                        // If AutoPause is enabled, unpause the emulator.
                                        // TODO: Always run this, even if !autoPause?
-                                       if (m_autoPause) {
-                                               doAutoPause(false);
+                                       if (d_ptr->autoPause) {
+                                               d_ptr->doAutoPause(false);
                                        }
                                        break;
                                default:
@@ -191,101 +292,4 @@ int EventLoop::processSdlEvent(const SDL_Event *event) {
        return ret;
 }
 
-/**
- * Toggle Fast Blur.
- */
-void EventLoop::doFastBlur(void)
-{
-       bool fastBlur = !m_vBackend->fastBlur();
-       m_vBackend->setFastBlur(fastBlur);
-
-       // Show an OSD message.
-       if (fastBlur) {
-               m_vBackend->osd_print(1500, "Fast Blur enabled.");
-       } else {
-               m_vBackend->osd_print(1500, "Fast Blur disabled.");
-       }
-}
-
-/**
- * Common pause processing function.
- * Called by doPause() and doAutoPause().
- */
-void EventLoop::doPauseProcessing(void)
-{
-       bool manual = m_paused.manual;
-       bool any = !!m_paused.data;
-       // TODO: Option to disable the Paused Effect?
-       // When enabled, it's only used for Manual Pause.
-       m_vBackend->setPausedEffect(manual);
-
-       // Reset the clocks and counters.
-       m_clks.reset();
-       // Pause audio.
-       m_sdlHandler->pause_audio(any);
-
-       // Update the window title.
-       if (manual) {
-               m_sdlHandler->set_window_title("Gens/GS II [SDL] [Paused]");
-       } else {
-               m_sdlHandler->set_window_title("Gens/GS II [SDL]");
-       }
-}
-
-/**
- * Pause/unpause emulation.
- */
-void EventLoop::doPause(void)
-{
-       m_paused.manual = !m_paused.manual;
-       doPauseProcessing();
-}
-
-/**
- * Pause/unpause emulation in response to window focus changes.
- * @param lostFocus True if window lost focus; false if window gained focus.
- */
-void EventLoop::doAutoPause(bool lostFocus)
-{
-       m_paused.focus = lostFocus;
-       doPauseProcessing();
-}
-
-/**
- * Show the "About" message.
- */
-void EventLoop::doAboutMessage(void)
-{
-       // TODO: OSD Gens logo as preview image, but with drop shadow disabled?
-       const uint64_t curTime = m_clks.timing.getTime();
-       if (m_lastF1time > 0 && (m_lastF1time + 5000000 > curTime)) {
-               // Timer hasn't expired.
-               // Don't show the message.
-               return;
-       }
-
-       // Version string.
-       string ver_str;
-       ver_str.reserve(512);
-       ver_str = "Gens/GS II - SDL2 frontend\n";
-       ver_str += "Version " + string(LibGens::version);
-       if (LibGens::version_vcs) {
-               ver_str += " (" + string(LibGens::version_vcs) + ')';
-       }
-       ver_str += '\n';
-       if (LibGens::version_desc) {
-               ver_str += string(LibGens::version_desc) + '\n';
-       }
-#if !defined(GENS_ENABLE_EMULATION)
-       ver_str += "[NO-EMULATION BUILD]\n";
-#endif
-       ver_str += "(c) 2008-2015 by David Korth.";
-
-       // Show a new message.
-       m_vBackend->osd_print(5000, ver_str.c_str());
-
-       // Save the current time.
-       m_lastF1time = curTime;
-}
-
 }
index dc2d505..408de79 100644 (file)
 #ifndef __GENS_SDL_EVENTLOOP_HPP__
 #define __GENS_SDL_EVENTLOOP_HPP__
 
-#include "libgens/Util/Timing.hpp"
 #include <SDL.h>
 
+// from qglobal.h (qt-4.8.6)
+// TODO: Move to a common header, along with implementations
+// of Q_DISABLE_COPY(), Q_D(), Q_Q(), etc.?
+#define EVENT_LOOP_DECLARE_PRIVATE(Class) \
+    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr); } \
+    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(d_ptr); } \
+    friend class Class##Private;
+
 namespace GensSdl {
 
-class SdlHandler;
 class VBackend;
 
+class EventLoopPrivate;
 class EventLoop
 {
        public:
-               EventLoop();
+               EventLoop(EventLoopPrivate *d);
                virtual ~EventLoop();
 
+       protected:
+               EventLoopPrivate *const d_ptr;
+               EVENT_LOOP_DECLARE_PRIVATE(EventLoop)
        private:
                // Q_DISABLE_COPY() equivalent.
                // TODO: Add GensSdl-specific version of Q_DISABLE_COPY().
@@ -50,6 +60,12 @@ class EventLoop
                 */
                virtual int run(const char *rom_filename) = 0;
 
+               /**
+                * Get the VBackend.
+                * @return VBackend.
+                */
+               VBackend *vBackend(void) const;
+
        protected:
                /**
                 * Process an SDL event.
@@ -57,99 +73,6 @@ class EventLoop
                 * @return 0 if the event was handled; non-zero if it wasn't.
                 */
                virtual int processSdlEvent(const SDL_Event *event);
-
-               /**
-                * Toggle Fast Blur.
-                */
-               void doFastBlur(void);
-
-               /**
-                * Common pause processing function.
-                * Called by doPause() and doAutoPause().
-                */
-               void doPauseProcessing(void);
-
-               /**
-                * Pause/unpause emulation.
-                */
-               void doPause(void);
-
-               /**
-                * Pause/unpause emulation in response to window focus changes.
-                * @param lostFocus True if window lost focus; false if window gained focus.
-                */
-               void doAutoPause(bool lostFocus);
-
-               /**
-                * Show the "About" message.
-                */
-               void doAboutMessage(void);
-
-       protected:
-               // TODO: Move to a private class?
-               bool m_running;
-               bool m_frameskip;
-
-               union paused_t {
-                       struct {
-                               uint8_t manual  : 1;    // Manual pause.
-                               uint8_t focus   : 1;    // Auto pause when focus is lost.
-                       };
-                       uint8_t data;
-               };
-               paused_t m_paused;
-
-               // Automatically pause when the window loses focus?
-               bool m_autoPause;
-
-               // Window has been exposed.
-               // Video should be updated if emulation is paused.
-               bool m_exposed;
-
-               class clks_t {
-                       public:
-                               // Reset frameskip timers.
-                               void reset(void) {
-                                       start_clk = timing.getTime();
-                                       old_clk = start_clk;
-                                       fps_clk = start_clk;
-                                       fps_clk = start_clk;
-                                       new_clk = start_clk;
-                                       usec_frameskip = 0;
-
-                                       // Frame counter.
-                                       frames = 0;
-                                       frames_old = 0;
-                                       fps = 0;
-                               }
-
-                               // Timing object.
-                               LibGens::Timing timing;
-
-                               // Clocks.
-                               uint64_t start_clk;
-                               uint64_t old_clk;
-                               uint64_t fps_clk;
-                               uint64_t new_clk;
-                               // Microsecond counter for frameskip.
-                               uint64_t usec_frameskip;
-
-                               // Frame counters.
-                               unsigned int frames;
-                               unsigned int frames_old;
-                               unsigned int fps;       // TODO: float or double?
-               };
-               clks_t m_clks;
-
-               // Last time the F1 message was displayed.
-               // This is here to prevent the user from spamming
-               // the display with the message.
-               uint64_t m_lastF1time;
-
-       public:
-               // TODO: Make this protected.
-               SdlHandler *m_sdlHandler;
-               VBackend *m_vBackend;
 };
 
 }
diff --git a/src/gens-sdl/EventLoop_p.hpp b/src/gens-sdl/EventLoop_p.hpp
new file mode 100644 (file)
index 0000000..f4f0e19
--- /dev/null
@@ -0,0 +1,166 @@
+/***************************************************************************
+ * gens-sdl: Gens/GS II basic SDL frontend.                                *
+ * EventLoop_p.hpp: Event loop base class. (PRIVATE CLASS)                 *
+ *                                                                         *
+ * Copyright (c) 2015 by David Korth.                                      *
+ *                                                                         *
+ * 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.           *
+ ***************************************************************************/
+
+#ifndef __GENS_SDL_EVENTLOOP_P_HPP__
+#define __GENS_SDL_EVENTLOOP_P_HPP__
+
+// OS-specific includes.
+#ifdef _WIN32
+// Windows
+#include <windows.h>
+// Win32 Unicode Translation Layer.
+// Needed for proper Unicode filename support on Windows.
+#include "libcompat/W32U/W32U_mini.h"
+#include "libcompat/W32U/W32U_argv.h"
+#else
+// Linux, Unix, Mac OS X
+#include <unistd.h>
+#endif
+
+// yield(), aka usleep(0) or Sleep(0)
+#ifdef _WIN32
+// Windows
+#define yield() do { Sleep(0); } while (0)
+#define usleep(usec) Sleep((DWORD)((usec) / 1000))
+#else
+// Linux, Unix, Mac OS X
+#define yield() do { usleep(0); } while (0)
+#endif
+
+#include "libgens/Util/Timing.hpp"
+
+namespace GensSdl {
+
+class SdlHandler;
+class VBackend;
+
+class EventLoopPrivate
+{
+       public:
+               EventLoopPrivate();
+               virtual ~EventLoopPrivate();
+
+       private:
+               // Q_DISABLE_COPY() equivalent.
+               // TODO: Add GensSdl-specific version of Q_DISABLE_COPY().
+               EventLoopPrivate(const EventLoopPrivate &);
+               EventLoopPrivate &operator=(const EventLoopPrivate &);
+
+       public:
+               /** Event handlers. **/
+
+               /**
+                * Toggle Fast Blur.
+                */
+               void doFastBlur(void);
+
+               /**
+                * Common pause processing function.
+                * Called by doPause() and doAutoPause().
+                */
+               void doPauseProcessing(void);
+
+               /**
+                * Pause/unpause emulation.
+                */
+               void doPause(void);
+
+               /**
+                * Pause/unpause emulation in response to window focus changes.
+                * @param lostFocus True if window lost focus; false if window gained focus.
+                */
+               void doAutoPause(bool lostFocus);
+
+               /**
+                * Show the "About" message.
+                */
+               void doAboutMessage(void);
+
+       public:
+               /** SDL handler and video backend. **/
+               SdlHandler *sdlHandler;
+               VBackend *vBackend;
+
+       public:
+               /** Internal variables. **/
+               bool running;
+               bool frameskip;
+
+               union paused_t {
+                       struct {
+                               uint8_t manual  : 1;    // Manual pause.
+                               uint8_t focus   : 1;    // Auto pause when focus is lost.
+                       };
+                       uint8_t data;
+               };
+               paused_t paused;
+
+               // Automatically pause when the window loses focus?
+               bool autoPause;
+
+               // Window has been exposed.
+               // Video should be updated if emulation is paused.
+               bool exposed;
+
+               class clks_t {
+                       public:
+                               // Reset frameskip timers.
+                               void reset(void) {
+                                       start_clk = timing.getTime();
+                                       old_clk = start_clk;
+                                       fps_clk = start_clk;
+                                       fps_clk = start_clk;
+                                       new_clk = start_clk;
+                                       usec_frameskip = 0;
+
+                                       // Frame counter.
+                                       frames = 0;
+                                       frames_old = 0;
+                                       fps = 0;
+                               }
+
+                               // Timing object.
+                               LibGens::Timing timing;
+
+                               // Clocks.
+                               uint64_t start_clk;
+                               uint64_t old_clk;
+                               uint64_t fps_clk;
+                               uint64_t new_clk;
+                               // Microsecond counter for frameskip.
+                               uint64_t usec_frameskip;
+
+                               // Frame counters.
+                               unsigned int frames;
+                               unsigned int frames_old;
+                               unsigned int fps;       // TODO: float or double?
+               };
+               clks_t clks;
+
+               // Last time the F1 message was displayed.
+               // This is here to prevent the user from spamming
+               // the display with the message.
+               uint64_t lastF1time;
+};
+
+}
+
+#endif /* __GENS_SDL_EVENTLOOP_P_HPP__ */
index d3df829..2de2aca 100644 (file)
@@ -148,8 +148,9 @@ static void gsdl_osd(OsdType osd_type, int param)
        }
 
        if (msg != nullptr) {
-               if (eventLoop->m_vBackend) {
-                       eventLoop->m_vBackend->osd_printf(1500, msg, param);
+               VBackend *vBackend = eventLoop->vBackend();
+               if (vBackend) {
+                       vBackend->osd_printf(1500, msg, param);
                } else {
                        // SDL handler hasn't been created yet.
                        // Store the message for later.
@@ -170,9 +171,10 @@ static void gsdl_osd(OsdType osd_type, int param)
 void checkForStartupMessages(void)
 {
        if (!startup_queue.empty()) {
+               VBackend *vBackend = eventLoop->vBackend();
                for (int i = 0; i < (int)startup_queue.size(); i++) {
                        const OsdStartup &startup = startup_queue.at(i);
-                       eventLoop->m_vBackend->osd_printf(startup.duration, startup.msg, startup.param);
+                       vBackend->osd_printf(startup.duration, startup.msg, startup.param);
                }
        }
 }