From 28d23ce3c076a141f8bb6fe294e408b004c91dc0 Mon Sep 17 00:00:00 2001
From: Michael Lotz <mmlr@mlotz.ch>
Date: Tue, 13 Oct 2015 22:46:23 +0000
Subject: [PATCH 1/5] Add LIB_INSTALL_DIR and INCLUDE_INSTALL_DIR in build
 system.

---
 CMakeLists.txt | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c6d638e..7fed177 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,6 +11,8 @@ SET(PATCH_LEVEL 2)
 SET(${PROJECT_NAME}_SOVERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL})
 SET(${PROJECT_NAME}_VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL})
 SET(LIB_SUFFIX "" CACHE STRING "Suffix to append to the system lib folder")
+SET(LIB_INSTALL_DIR lib CACHE STRING "Library install directory")
+SET(INCLUDE_INSTALL_DIR include CACHE STRING "Include install directory")
 
 # set default cmake build type to RelWithDebInfo (None Debug Release RelWithDebInfo MinSizeRel)
 #IF( NOT CMAKE_BUILD_TYPE )
@@ -94,14 +96,14 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
    OUTPUT_NAME ${PROJECT_NAME}  # Avoid conflicts between library and binary target names 
    COMPILE_DEFINITIONS "FIFECHAN_BUILD"
    )
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib${LIB_SUFFIX} PERMISSIONS
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}${LIB_SUFFIX} PERMISSIONS
   OWNER_READ OWNER_WRITE OWNER_EXECUTE
   GROUP_READ GROUP_EXECUTE
   WORLD_READ WORLD_EXECUTE)
-INSTALL(FILES ${FIFECHAN_HEADER} DESTINATION include/)
-INSTALL(FILES ${FIFECHAN_HEADERS} DESTINATION include/fifechan/)
-INSTALL(FILES ${FIFECHAN_WIDGET_HEADERS} DESTINATION include/fifechan/widgets/)
-INSTALL(FILES ${FIFECHAN_CONTRIB_WIDGET_HEADERS} DESTINATION include/fifechan/contrib/widgets/)
+INSTALL(FILES ${FIFECHAN_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR})
+INSTALL(FILES ${FIFECHAN_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/)
+INSTALL(FILES ${FIFECHAN_WIDGET_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/widgets/)
+INSTALL(FILES ${FIFECHAN_CONTRIB_WIDGET_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/contrib/widgets/)
 
 #REMOVE_DEFINITIONS("-DFIFECHAN_BUILD")
 #ADD_DEFINITIONS("-DFIFECHAN_EXTENSION_BUILD")
@@ -147,13 +149,13 @@ IF(ENABLE_ALLEGRO AND ALLEGRO_FOUND)
      COMPILE_DEFINITIONS "FIFECHAN_EXTENSION_BUILD"
      )
 
-   INSTALL(TARGETS ${PROJECT_NAME}_allegro DESTINATION lib${LIB_SUFFIX} PERMISSIONS
+   INSTALL(TARGETS ${PROJECT_NAME}_allegro DESTINATION ${LIB_INSTALL_DIR}${LIB_SUFFIX} PERMISSIONS
      OWNER_READ OWNER_WRITE OWNER_EXECUTE
      GROUP_READ GROUP_EXECUTE
      WORLD_READ WORLD_EXECUTE)
-   INSTALL(FILES ${FIFECHAN_ALLEGRO_HEADER} DESTINATION include/fifechan/)
-   INSTALL(FILES ${FIFECHAN_ALLEGRO_HEADERS} DESTINATION include/fifechan/allegro/)
-   INSTALL(FILES ${FIFECHAN_ALLEGRO_CONTRIB_HEADERS} DESTINATION include/fifechan/contrib/allegro/)   
+   INSTALL(FILES ${FIFECHAN_ALLEGRO_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/)
+   INSTALL(FILES ${FIFECHAN_ALLEGRO_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/allegro/)
+   INSTALL(FILES ${FIFECHAN_ALLEGRO_CONTRIB_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/contrib/allegro/)
 ENDIF(ENABLE_ALLEGRO AND ALLEGRO_FOUND)
 
 # The Fifechan Irrlicht extension library
@@ -194,12 +196,12 @@ IF(ENABLE_IRRLICHT AND IRRLICHT_FOUND)
      COMPILE_DEFINITIONS "FIFECHAN_EXTENSION_BUILD"
      )
 
-   INSTALL(TARGETS ${PROJECT_NAME}_irrlicht DESTINATION lib${LIB_SUFFIX} PERMISSIONS
+   INSTALL(TARGETS ${PROJECT_NAME}_irrlicht DESTINATION ${LIB_INSTALL_DIR}${LIB_SUFFIX} PERMISSIONS
      OWNER_READ OWNER_WRITE OWNER_EXECUTE
      GROUP_READ GROUP_EXECUTE
      WORLD_READ WORLD_EXECUTE)
-   INSTALL(FILES ${FIFECHAN_IRRLICHT_HEADER} DESTINATION include/fifechan/)
-   INSTALL(FILES ${FIFECHAN_IRRLICHT_HEADERS} DESTINATION include/fifechan/irrlicht/)
+   INSTALL(FILES ${FIFECHAN_IRRLICHT_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/)
+   INSTALL(FILES ${FIFECHAN_IRRLICHT_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/irrlicht/)
 ENDIF(ENABLE_IRRLICHT AND IRRLICHT_FOUND)
 
 # The Fifechan OpenGL extension library
@@ -274,13 +276,13 @@ IF(ENABLE_OPENGL AND OPENGL_FOUND)
     COMPILE_DEFINITIONS "FIFECHAN_EXTENSION_BUILD"
     )
 
-  INSTALL(TARGETS ${PROJECT_NAME}_opengl DESTINATION lib${LIB_SUFFIX} PERMISSIONS
+  INSTALL(TARGETS ${PROJECT_NAME}_opengl DESTINATION ${LIB_INSTALL_DIR}${LIB_SUFFIX} PERMISSIONS
     OWNER_READ OWNER_WRITE OWNER_EXECUTE
     GROUP_READ GROUP_EXECUTE
     WORLD_READ WORLD_EXECUTE)
-  INSTALL(FILES ${FIFECHAN_OPENGL_HEADER} DESTINATION include/fifechan/)
-  INSTALL(FILES ${FIFECHAN_OPENGL_HEADERS} DESTINATION include/fifechan/opengl/)
-  INSTALL(FILES ${FIFECHAN_OPENGL_CONTRIB_HEADERS} DESTINATION include/fifechan/contrib/opengl/)   
+  INSTALL(FILES ${FIFECHAN_OPENGL_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/)
+  INSTALL(FILES ${FIFECHAN_OPENGL_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/opengl/)
+  INSTALL(FILES ${FIFECHAN_OPENGL_CONTRIB_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/contrib/opengl/)
 ENDIF(ENABLE_OPENGL AND OPENGL_FOUND)
 
 # The Fifechan SDL extension library
@@ -347,13 +349,13 @@ IF(ENABLE_SDL AND SDL_FOUND AND SDLIMAGE_FOUND)
     COMPILE_DEFINITIONS "FIFECHAN_EXTENSION_BUILD"
     )
 
-  INSTALL(TARGETS ${PROJECT_NAME}_sdl DESTINATION lib${LIB_SUFFIX} PERMISSIONS
+  INSTALL(TARGETS ${PROJECT_NAME}_sdl DESTINATION ${LIB_INSTALL_DIR}${LIB_SUFFIX} PERMISSIONS
     OWNER_READ OWNER_WRITE OWNER_EXECUTE
     GROUP_READ GROUP_EXECUTE
     WORLD_READ WORLD_EXECUTE)
-  INSTALL(FILES ${FIFECHAN_SDL_HEADER} DESTINATION include/fifechan/)
-  INSTALL(FILES ${FIFECHAN_SDL_HEADERS} DESTINATION include/fifechan/sdl/)
-  INSTALL(FILES ${FIFECHAN_SDL_CONTRIB_HEADERS} DESTINATION include/fifechan/contrib/sdl/)   
+  INSTALL(FILES ${FIFECHAN_SDL_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/)
+  INSTALL(FILES ${FIFECHAN_SDL_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/sdl/)
+  INSTALL(FILES ${FIFECHAN_SDL_CONTRIB_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/fifechan/contrib/sdl/)
 ENDIF(ENABLE_SDL AND SDL_FOUND AND SDLIMAGE_FOUND)
 
 # Make uninstall target
-- 
2.2.2


From 60abc7fabb4e4e10d3398771c80497f6b0eb4d9b Mon Sep 17 00:00:00 2001
From: Michael Lotz <mmlr@mlotz.ch>
Date: Sat, 31 Oct 2015 15:38:58 +0000
Subject: [PATCH 2/5] Make build system Haiku aware to actually link required
 libs.

Previously the libraries didn't actually link to their dependencies.
---
 CMakeLists.txt | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7fed177..7c06c2f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -210,11 +210,11 @@ OPTION(ENABLE_OPENGL_CONTRIB "Enabled the Fifechan OpenGL Contrib extension" OFF
 OPTION(BUILD_FIFECHAN_OPENGL_SHARED "Build the Fifechan OpenGL extension library as a shared library." ON)
 FIND_PACKAGE(OpenGL)
 
-IF(APPLE AND ENABLE_OPENGL)
+IF((APPLE OR HAIKU) AND ENABLE_OPENGL)
   FIND_LIBRARY(OPENGL_LIBRARY OpenGL)
   MARK_AS_ADVANCED(OPENGL_LIBRARY)
   SET(EXTRA_LIBS ${OPENGL_LIBRARY})
-ENDIF(APPLE AND ENABLE_OPENGL)
+ENDIF((APPLE OR HAIKU) AND ENABLE_OPENGL)
 
 IF(ENABLE_OPENGL_CONTRIB)
  FIND_PACKAGE(OGLFT)
@@ -266,6 +266,9 @@ IF(ENABLE_OPENGL AND OPENGL_FOUND)
     TARGET_LINK_LIBRARIES(${PROJECT_NAME}_opengl ${OPENGL_LIBRARY} ${PROJECT_NAME})
     ENDIF(ENABLE_OPENGL_CONTRIB AND OpenGL-FT_FOUND)
   ENDIF(APPLE)
+  IF(HAIKU)
+    TARGET_LINK_LIBRARIES(${PROJECT_NAME}_opengl ${OPENGL_LIBRARY} ${PROJECT_NAME})
+  ENDIF(HAIKU)
 
   ADD_CUSTOM_TARGET(opengllib DEPENDS ${PROJECT_NAME}_opengl) # Create symlink
   SET_TARGET_PROPERTIES(${PROJECT_NAME}_opengl PROPERTIES
@@ -295,12 +298,12 @@ IF(ENABLE_SDL_CONTRIB)
 FIND_PACKAGE(SDL_ttf)
 ENDIF(ENABLE_SDL_CONTRIB)
 
-IF(APPLE AND ENABLE_SDL)
+IF((APPLE OR HAIKU) AND ENABLE_SDL)
   FIND_LIBRARY(SDL_LIBRARY SDL)
   FIND_LIBRARY(SDLIMAGE_LIBRARY SDL_image)
   MARK_AS_ADVANCED(SDL_LIBRARY SDLIMAGE_LIBRARY)
   SET(EXTRA_LIBS ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY})
-ENDIF(APPLE AND ENABLE_SDL)
+ENDIF((APPLE OR HAIKU) AND ENABLE_SDL)
 IF(ENABLE_SDL AND SDL_FOUND AND SDLIMAGE_FOUND)  
  
   INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR} ${SDLIMAGE_INCLUDE_DIR})
@@ -340,6 +343,9 @@ IF(ENABLE_SDL AND SDL_FOUND AND SDLIMAGE_FOUND)
   IF(APPLE)
     TARGET_LINK_LIBRARIES(${PROJECT_NAME}_sdl ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} SDLmain ${PROJECT_NAME})
   ENDIF(APPLE)
+  IF(HAIKU)
+    TARGET_LINK_LIBRARIES(${PROJECT_NAME}_sdl ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${PROJECT_NAME})
+  ENDIF(HAIKU)
   ADD_CUSTOM_TARGET(sdllib DEPENDS ${PROJECT_NAME}_sdl) # Create symlink
   SET_TARGET_PROPERTIES(${PROJECT_NAME}_sdl PROPERTIES
     VERSION ${${PROJECT_NAME}_VERSION}
-- 
2.2.2


From 931f7327361a86accb771ce539495fbcff6f2873 Mon Sep 17 00:00:00 2001
From: Michael Lotz <mmlr@mlotz.ch>
Date: Wed, 28 Oct 2015 02:17:16 +0000
Subject: [PATCH 3/5] Fix casting of 16 bit buffer in SDL blending function.

The buffer was erroneously cast to Uint32 leading to reads past the
allocation for the very last pixel.
---
 include/fifechan/sdl/sdlpixel.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/fifechan/sdl/sdlpixel.hpp b/include/fifechan/sdl/sdlpixel.hpp
index 665d976..5470570 100644
--- a/include/fifechan/sdl/sdlpixel.hpp
+++ b/include/fifechan/sdl/sdlpixel.hpp
@@ -243,7 +243,7 @@ namespace fcn
               break;
 
           case 2:
-              *(Uint16 *)p = SDLAlpha16(pixel, *(Uint32 *)p, color.a, surface->format);
+              *(Uint16 *)p = SDLAlpha16(pixel, *(Uint16 *)p, color.a, surface->format);
               break;
 
           case 3:
-- 
2.2.2


From be2540efa64a2a30095a3e2d09cf676b4265e5f3 Mon Sep 17 00:00:00 2001
From: Michael Lotz <mmlr@mlotz.ch>
Date: Wed, 28 Oct 2015 02:22:01 +0000
Subject: [PATCH 4/5] Avoid needless SDL blending operation for fully opaque
 pixels.

This avoids some overhead and truncation artefacts.
---
 include/fifechan/sdl/sdlpixel.hpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/fifechan/sdl/sdlpixel.hpp b/include/fifechan/sdl/sdlpixel.hpp
index 5470570..5332c59 100644
--- a/include/fifechan/sdl/sdlpixel.hpp
+++ b/include/fifechan/sdl/sdlpixel.hpp
@@ -228,6 +228,11 @@ namespace fcn
      */
     inline void SDLputPixelAlpha(SDL_Surface* surface, int x, int y, const Color& color)
     {
+        if (color.a == 255) {
+            SDLputPixel(surface, x, y, color);
+            return;
+        }
+
         int bpp = surface->format->BytesPerPixel;
 
         SDL_LockSurface(surface);
-- 
2.2.2


From a3adac2f041867b02d2dce10cf4cc788f9d46db6 Mon Sep 17 00:00:00 2001
From: Michael Lotz <mmlr@mlotz.ch>
Date: Sat, 31 Oct 2015 15:21:24 +0000
Subject: [PATCH 5/5] Replace individual SDL blending functions with generic
 ones.

The base blending formula is changed to the one found in SDL_gfx
which produces better output.
---
 include/fifechan/sdl/sdlpixel.hpp | 75 ++++++++++++++++++++-------------------
 src/sdl/sdlgraphics.cpp           |  4 +--
 2 files changed, 41 insertions(+), 38 deletions(-)

diff --git a/include/fifechan/sdl/sdlpixel.hpp b/include/fifechan/sdl/sdlpixel.hpp
index 5332c59..7232d70 100644
--- a/include/fifechan/sdl/sdlpixel.hpp
+++ b/include/fifechan/sdl/sdlpixel.hpp
@@ -175,35 +175,31 @@ namespace fcn
     }
 
     /**
-     * Blends two 32 bit colors together.
+     * Blends two color components together.
      *
-     * @param src the source color.
-     * @param dst the destination color.
-     * @param a alpha.
+     * @param source the source value.
+     * @param dest the destination value.
+     * @param alpha alpha.
      */
-    inline unsigned int SDLAlpha32(unsigned int src, unsigned int dst, unsigned char a)
+    template<typename T>
+    inline T SDLBlend(T source, T dest, unsigned char alpha)
     {
-        unsigned int b = ((src & 0xff) * a + (dst & 0xff) * (255 - a)) >> 8;
-        unsigned int g = ((src & 0xff00) * a + (dst & 0xff00) * (255 - a)) >> 8;
-        unsigned int r = ((src & 0xff0000) * a + (dst & 0xff0000) * (255 - a)) >> 8;
-
-        return (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
+        return dest + ((source - dest) * alpha >> 8);
     }
 
     /**
-     * Blends two 16 bit colors together.
+     * Blends two colors together.
      *
      * @param src the source color.
      * @param dst the destination color.
      * @param a alpha.
      */
-    inline unsigned short SDLAlpha16(unsigned short src, unsigned short dst, unsigned char a, const SDL_PixelFormat *f)
+    template<typename T>
+    inline T SDLBlendColor(T src, T dst, unsigned char alpha, const SDL_PixelFormat *f)
     {
-        unsigned int b = ((src & f->Rmask) * a + (dst & f->Rmask) * (255 - a)) >> 8;
-        unsigned int g = ((src & f->Gmask) * a + (dst & f->Gmask) * (255 - a)) >> 8;
-        unsigned int r = ((src & f->Bmask) * a + (dst & f->Bmask) * (255 - a)) >> 8;
-
-        return (unsigned short)((b & f->Rmask) | (g & f->Gmask) | (r & f->Bmask));
+        return (SDLBlend(src & f->Rmask, dst & f->Rmask, alpha) & f->Rmask)
+            | (SDLBlend(src & f->Gmask, dst & f->Gmask, alpha) & f->Gmask)
+            | (SDLBlend(src & f->Bmask, dst & f->Bmask, alpha) & f->Bmask);
     }
 
     /*
@@ -239,44 +235,51 @@ namespace fcn
 
         Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
 
-        Uint32 pixel = SDL_MapRGB(surface->format, color.r, color.g, color.b);
-
         switch(bpp)
         {
           case 1:
-              *p = pixel;
+          {
+              Uint32 pixel = SDL_MapRGB(surface->format, color.r, color.g, color.b);
+
+              SDL_Color *colors = surface->format->palette->colors;
+              SDL_Color &sourceColor = colors[pixel];
+              SDL_Color &destColor = colors[*p];
+
+              *p = SDL_MapRGB(surface->format,
+                  SDLBlend(sourceColor.r, destColor.r, color.a),
+                  SDLBlend(sourceColor.g, destColor.g, color.a),
+                  SDLBlend(sourceColor.b, destColor.b, color.a));
               break;
+          }
 
           case 2:
-              *(Uint16 *)p = SDLAlpha16(pixel, *(Uint16 *)p, color.a, surface->format);
+          {
+              Uint32 pixel = SDL_MapRGB(surface->format, color.r, color.g, color.b);
+              *(Uint16 *)p = SDLBlendColor<Uint16>(pixel, *(Uint16 *)p, color.a, surface->format);
               break;
+          }
 
           case 3:
               if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
               {
-                  unsigned int r = (p[0] * (255 - color.a) + color.r * color.a) >> 8;
-                  unsigned int g = (p[1] * (255 - color.a) + color.g * color.a) >> 8;
-                  unsigned int b = (p[2] * (255 - color.a) + color.b * color.a) >> 8;
-
-                  p[2] = b;
-                  p[1] = g;
-                  p[0] = r;
+                  p[0] = SDLBlend<Uint8>(color.r, p[0], color.a);
+                  p[1] = SDLBlend<Uint8>(color.g, p[1], color.a);
+                  p[2] = SDLBlend<Uint8>(color.b, p[2], color.a);
               }
               else
               {
-                  unsigned int r = (p[2] * (255 - color.a) + color.r * color.a) >> 8;
-                  unsigned int g = (p[1] * (255 - color.a) + color.g * color.a) >> 8;
-                  unsigned int b = (p[0] * (255 - color.a) + color.b * color.a) >> 8;
-
-                  p[0] = b;
-                  p[1] = g;
-                  p[2] = r;
+                  p[0] = SDLBlend<Uint8>(color.b, p[0], color.a);
+                  p[1] = SDLBlend<Uint8>(color.g, p[1], color.a);
+                  p[2] = SDLBlend<Uint8>(color.r, p[2], color.a);
               }
               break;
 
           case 4:
-              *(Uint32 *)p = SDLAlpha32(pixel, *(Uint32 *)p, color.a);
+          {
+              Uint32 pixel = SDL_MapRGB(surface->format, color.r, color.g, color.b);
+              *(Uint32 *)p = SDLBlendColor<Uint32>(pixel, *(Uint32 *)p, color.a, surface->format);
               break;
+          }
         }
 
         SDL_UnlockSurface(surface);
diff --git a/src/sdl/sdlgraphics.cpp b/src/sdl/sdlgraphics.cpp
index ce135a1..d641271 100644
--- a/src/sdl/sdlgraphics.cpp
+++ b/src/sdl/sdlgraphics.cpp
@@ -364,7 +364,7 @@ namespace fcn
                 {
                     if (mAlpha)
                     {
-                        *q = SDLAlpha32(pixel,*q,mColor.a);
+                        *q = SDLBlendColor<Uint32>(pixel,*q,mColor.a,mTarget->format);
                         q++;
                     }
                     else
@@ -479,7 +479,7 @@ namespace fcn
               {
                   if (mAlpha)
                   {
-                      *(Uint32*)p = SDLAlpha32(pixel,*(Uint32*)p,mColor.a);
+                      *(Uint32*)p = SDLBlendColor<Uint32>(pixel,*(Uint32*)p,mColor.a,mTarget->format);
                   }
                   else
                   {
-- 
2.2.2

