workaround a problem with the harmattan gcc
[drnoksnes] / platform / sdlvscalers.cpp
index cd48c33..ab3dd56 100644 (file)
@@ -6,6 +6,7 @@
 #include <SDL.h>
 
 #if CONF_XSP
+#      include <SDL_syswm.h>
 #      include <X11/extensions/Xsp.h>
 #endif
 #if CONF_HD
@@ -13,7 +14,6 @@
 #endif
 
 #include "snes9x.h"
-#include "display.h"
 #include "platform.h"
 #include "sdlv.h"
 
@@ -31,6 +31,8 @@ static void centerRectangle(SDL_Rect& result, int areaW, int areaH, int w, int h
        result.w = w;
        result.y = areaH / 2 - h / 2;
        result.h = h;
+       /* We need to keep this 4-byte aligned (each pixel is 2-byte) */
+       result.x &= ~1;
 }
 
 /* Base scaler for stupid scalers */
@@ -103,10 +105,14 @@ public:
                x = 1.0f; y = 1.0f;
        };
 
-       virtual void prepare() { };
+       virtual void prepare()
+       {
+               if (SDL_MUSTLOCK(m_screen)) SDL_LockSurface(m_screen);
+       };
 
        virtual void finish()
        {
+               if (SDL_MUSTLOCK(m_screen)) SDL_UnlockSurface(m_screen);
                SDL_UpdateRects(m_screen, 1, &m_area);
        };
 
@@ -289,10 +295,13 @@ public:
                x = 2.0f; y = 2.0f;
        };
 
-       void prepare() { };
+       void prepare() {
+               SDL_FillRect(m_screen, NULL, 0);
+       };
 
        void finish()
        {
+               if (SDL_MUSTLOCK(m_screen)) SDL_LockSurface(m_screen);
                uint16 * src = reinterpret_cast<uint16*>(m_surface);
                uint16 * dst = reinterpret_cast<uint16*>(
                        ((uint8*) m_screen->pixels)
@@ -353,7 +362,13 @@ public:
                        if (y&1) src += src_pitch;
                }
 
-               SDL_UpdateRects(m_screen, 1, &m_area);
+               if (SDL_MUSTLOCK(m_screen)) SDL_UnlockSurface(m_screen);
+
+               if (m_screen->flags & SDL_DOUBLEBUF) {
+                       SDL_Flip(m_screen);
+               } else {
+                       SDL_UpdateRects(m_screen, 1, &m_area);
+               }
        };
 
        void pause() { };
@@ -372,20 +387,30 @@ class HAAScalerBase : public Scaler
        const int m_w, m_h, m_Bpp;
        const float ratio_x, ratio_y;
 
+       static bool initialized;
+
 protected:
        HAAScalerBase(SDL_Surface* screen, int w, int h, float r_x, float r_y)
        : m_screen(screen), m_w(w), m_h(h),
         m_Bpp(m_screen->format->BitsPerPixel / 8),
         ratio_x(r_x), ratio_y(r_y)
        {
+               const bool fullscreen = m_screen->flags & SDL_FULLSCREEN;
                centerRectangle(m_area, GUI.Width, GUI.Height, w * r_x, h * r_y);
 
                // Clear the SDL screen with black, just in case it gets drawn.
                SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
 
-               HAA_Init(m_screen->flags & SDL_FULLSCREEN);
+               if (!initialized) {
+                       HAA_Init(0);
+                       initialized = true;
+               } else {
+                       HAA_SetVideoMode(); // Tell HAA we might have changed video mode
+               }
+
                actor = HAA_CreateActor(0, m_w, m_h, m_screen->format->BitsPerPixel);
-               HAA_SetPosition(actor, m_area.x, m_area.y + 60);
+               HAA_SetPosition(actor, m_area.x, m_area.y + (fullscreen ? 0 : 60));
+                       // In windowed mode, take care of the title bar (xoffset = 60)
                HAA_SetScale(actor, r_x, r_y);
                HAA_Show(actor);
        }
@@ -394,7 +419,6 @@ public:
        virtual ~HAAScalerBase()
        {
                HAA_FreeActor(actor);
-               HAA_Quit();
        };
 
        uint8* getDrawBuffer() const
@@ -436,6 +460,7 @@ public:
                return HAA_FilterEvent(&event) == 0;
        };
 };
+bool HAAScalerBase::initialized = false;
 
 class HAAFillScaler : public HAAScalerBase
 {