/*
  libuta - a C++ widget library based on SDL (Simple Direct Layer)
  Copyright (C) 1999-2002  Karsten Laux

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library 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
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA  02111-1307, SA.
*/

// written by Karsten Laux, March 2001 

#ifndef _BLITTERS_H_
#define _BLITTERS_H_

#include "point.h"
#include "rect.h"
#include "surface.h"
#include "debug.h"

#if defined(__i386__)
#define X86_ASSEMBLER
#else
#undef X86_ASSEMBLER
#endif

#ifdef X86_ASSEMBLER
extern "C" 
{ 
#include "mmx.h" 
}
#endif

namespace uta {

/** Test if MMX accelerated blitters are available. 
 */
inline bool hasMMXExtension()
  {
#ifdef X86_ASSEMBLER
    int features = mm_support();
    debug(
	  std::cerr << "processor features: " ;
	  if(features & 0x01)
	  std::cerr << "MMX ";
	  if(features == 3)
	  std::cerr << "Extended MMX ";
	  if(features == 5)
	  std::cerr << "3DNow! ";
	  std::cerr << std::endl;
	  );
    return (features & 0x01);
#else
    return false;
#endif
  }

/** Apply const gamma value.
    Blit just copies alpha value of the source to the destination surface.
 */
void gammablit_RGBA8888_RGBA8888(Surface* dst, const Surface* src, 
				 char g, 
				 const Rect& srcRect, const Point& dstPoint);

/** Convert RGBA8888 to RGB565 and apply const gamma value.
    This blit ignores the alpha channel of the source surface.
 */
void gammablit_RGBA8888_RGB565(Surface* dst, const Surface* src, 
			       char g, 
			       const Rect& srcRect, const Point& dstPoint);
 
/** Apply const gamma value.
 */
void gammablit_RGB565_RGB565(Surface* dst, const Surface* src, 
			     char g, 
			     const Rect& srcRect, const Point& dstPoint);
 
/** Apply per pixel gamma value.
    Blit just copies alpha value of the source to the destination surface.
 */
void gammablit_RGBA8888_RGBA8888(Surface* dst, const Surface* src, 
				 GammaFunction* func, 
				 const Rect& srcRect, const Point& dstPoint);

/** Convert RGBA8888 to RGB565 and apply per pixel gamma value.
    This blit ignores the alpha channel of the source surface.
 */
void gammablit_RGBA8888_RGB565(Surface* dst, const Surface* src, 
			       GammaFunction* func, 
			       const Rect& srcRect, const Point& dstPoint);

/** Apply per pixel gamma value.
 */
void gammablit_RGB565_RGB565(Surface* dst, const Surface* src, 
			     GammaFunction* func, 
			     const Rect& srcRect, const Point& dstPoint);

/** Blit using const gamma value.
 *  Very slow but compatible C implementation
 */
void gammablit_C(Surface* dst, const Surface* src, 
	       char g, 
	       const Rect& srcRect, const Point& dstPoint);

/** Apply per pixel gamma value.
 *  Very slow but compatible C implementation 
 */
void gammablit_C(Surface* dst, const Surface* src, 
		GammaFunction* func, 
		const Rect& srcRect, const Point& dstPoint);

/** Blit using const gamma value.
 *  This blits makes use of the optimized functions if possible.
 */
void gammablit(Surface* dst, const Surface* src, 
	       char g, 
	       const Rect& srcRect, const Point& dstPoint);

/** Apply per pixel gamma value.
 *  This blits makes use of the optimized functions if possible.
 */
void gammablit(Surface* dst, const Surface* src, 
		GammaFunction* func, 
		const Rect& srcRect, const Point& dstPoint);
}


#endif
  
