📄 algo2d.h
字号:
//////////////////////////////////////////////////////////////////////////////
//
// PocketFrog - The Game Library for Pocket PC Devices
// Copyright 2002 Thierry Tremblay
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Thierry Tremblay makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef POCKETFROG_ALGO2D_H
#define POCKETFROG_ALGO2D_H
#include "../defs.h"
#include <PocketHAL/surface.h>
namespace Frog {
namespace Internal {
//////////////////////////////////////////////////////////////////////////////
//
// todo: STL stuff needed until the new shaders are in place
//
//////////////////////////////////////////////////////////////////////////////
template <class _InputIter, class _OutputIter, class _UnaryOperation>
inline _OutputIter
transform( _InputIter __first, _InputIter __last,
_OutputIter __result,
_UnaryOperation __unary_op )
{
for ( ; __first != __last; ++__first, ++__result)
*__result = __unary_op( *__first );
return __result;
}
template <class _InputIter1, class _InputIter2, class _OutputIter, class _BinaryOperation>
inline _OutputIter
transform( _InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2,
_OutputIter __result,
_BinaryOperation __binary_op )
{
for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result)
*__result = __binary_op(*__first1, *__first2);
return __result;
}
template <class _InputIter1, class _InputIter2, class _OutputIter, class _Predicate, class _BinaryOperation>
inline _OutputIter
transform_if( _InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2,
_OutputIter __result,
_Predicate __pred, _BinaryOperation __binary_op )
{
for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result)
if (__pred(*__first1)) *__result = __binary_op(*__first1, *__first2);
return __result;
}
template<class _A, class _R>
struct unary_function
{
typedef _A argument_type;
typedef _R result_type;
};
template<class _A1, class _A2, class _R>
struct binary_function {
typedef _A1 first_argument_type;
typedef _A2 second_argument_type;
typedef _R result_type;
};
template<class _Bfn>
class binder1st
: public unary_function<typename _Bfn::second_argument_type, typename _Bfn::result_type>
{
public:
binder1st(const _Bfn& _X, const typename _Bfn::first_argument_type& _Y)
: op(_X), value(_Y) {}
result_type operator()(const argument_type& _X) const
{return (op(value, _X)); }
protected:
_Bfn op;
typename _Bfn::first_argument_type value;
};
template<class _Bfn>
class binder2nd
: public unary_function<typename _Bfn::first_argument_type,
typename _Bfn::result_type> {
public:
binder2nd(const _Bfn& _X,
const typename _Bfn::second_argument_type& _Y)
: op(_X), value(_Y) {}
result_type operator()(const argument_type& _X) const
{return (op(_X, value)); }
protected:
_Bfn op;
typename _Bfn::second_argument_type value;
};
template<class _Bfn, class _Ty> inline
binder2nd<_Bfn> bind2nd(const _Bfn& _X, const _Ty& _Y)
{return (binder2nd<_Bfn>(_X,
_Bfn::second_argument_type(_Y))); }
template<class _Bfn, class _Ty> inline
binder1st<_Bfn> bind1st(const _Bfn& _X, const _Ty& _Y)
{
return (binder1st<_Bfn>(_X, _Bfn::first_argument_type(_Y)));
}
template<class _Ty>
struct not_equal_to : binary_function<_Ty, _Ty, bool> {
bool operator()(const _Ty& _X, const _Ty& _Y) const
{return (_X != _Y); }
};
namespace Algo2D {
//////////////////////////////////////////////////////////////////////////////
//
// 2D Raster Algorithms
//
//////////////////////////////////////////////////////////////////////////////
template<typename PixelFunction> inline
void Blit( PixelFunction& F, PHAL::Surface& buffer, const Rect& destRect, const PHAL::Surface& source, const Rect& srcRect )
{
const Pixel* pSrc = source.GetPixels( srcRect.left, srcRect.top );
Pixel* pDest = buffer.GetPixels( destRect.left, destRect.top );
int width = srcRect.GetWidth();
for ( int h = srcRect.GetHeight(); h; --h )
{
transform( pSrc, pSrc + width, pDest, pDest, F );
pSrc = (Pixel*)((uint8_t*)pSrc + source.GetPitch());
pDest = (Pixel*)((uint8_t*)pDest + buffer.GetPitch());
}
}
template<typename PixelFunction> inline
void BlitMask( PixelFunction& F, PHAL::Surface& buffer, const Rect& destRect, const PHAL::Surface& source, const Rect& srcRect, Pixel mask )
{
const Pixel* pSrc = source.GetPixels( srcRect.left, srcRect.top );
Pixel* pDest = buffer.GetPixels( destRect.left, destRect.top );
int width = srcRect.GetWidth();
for ( int h = srcRect.GetHeight(); h; --h )
{
transform_if( pSrc, pSrc + width, pDest, pDest, bind2nd( not_equal_to<Pixel>(), mask ), F );
pSrc = (Pixel*)((uint8_t*)pSrc + source.GetPitch());
pDest = (Pixel*)((uint8_t*)pDest + buffer.GetPitch());
}
}
template<typename PixelFunction> inline
void BlitTransform( PixelFunction& F, PHAL::Surface& buffer, const Rect& destRect, const unsigned transform[3][2], const PHAL::Surface& source )
{
unsigned y1 = (destRect.top << 6) + (1<<5);
unsigned y2 = (destRect.bottom << 6) + (1<<5);
unsigned x1 = (destRect.left << 6) + (1<<5);
unsigned x2 = (destRect.right << 6) + (1<<5);
unsigned u0 = x1 * transform[0][0] + y1 * transform[1][0] + transform[2][0];
unsigned v0 = x1 * transform[0][1] + y1 * transform[1][1] + transform[2][1];
unsigned dudx = transform[0][0] << 6;
unsigned dvdx = transform[0][1] << 6;
unsigned dudy = transform[1][0] << 6;
unsigned dvdy = transform[1][1] << 6;
for (unsigned dy = y1; dy != y2; dy += (1<<6) )
{
Pixel* dest = buffer.GetPixels( x1 >> 6, dy >> 6 );
unsigned u = u0;
unsigned v = v0;
for (unsigned dx = x1; dx != x2; dx += (1<<6) )
{
unsigned ix = u >> 16;
unsigned iy = v >> 16;
if (ix < (unsigned)source.GetWidth() && iy < (unsigned)source.GetHeight() )
{
*dest = F( *source.GetPixels(ix,iy), *dest );
}
u += dudx;
v += dvdx;
++dest;
}
u0 += dudy;
v0 += dvdy;
}
}
template<typename PixelFunction> inline
void BlitTransformMask( PixelFunction& F, PHAL::Surface& buffer, const Rect& destRect, const unsigned transform[3][2], const PHAL::Surface& source, Pixel mask )
{
unsigned y1 = (destRect.top << 6) + (1<<5);
unsigned y2 = (destRect.bottom << 6) + (1<<5);
unsigned x1 = (destRect.left << 6) + (1<<5);
unsigned x2 = (destRect.right << 6) + (1<<5);
unsigned u0 = x1 * transform[0][0] + y1 * transform[1][0] + transform[2][0];
unsigned v0 = x1 * transform[0][1] + y1 * transform[1][1] + transform[2][1];
unsigned dudx = transform[0][0] << 6;
unsigned dvdx = transform[0][1] << 6;
unsigned dudy = transform[1][0] << 6;
unsigned dvdy = transform[1][1] << 6;
for (unsigned dy = y1; dy != y2; dy += (1<<6) )
{
Pixel* dest = buffer.GetPixels( x1 >> 6, dy >> 6 );
unsigned u = u0;
unsigned v = v0;
for (unsigned dx = x1; dx != x2; dx += (1<<6) )
{
unsigned ix = u >> 16;
unsigned iy = v >> 16;
if (ix < (unsigned)source.GetWidth() && iy < (unsigned)source.GetHeight() )
{
const Pixel& src = *source.GetPixels(ix,iy);
if (src != mask)
{
*dest = F( src, *dest );
}
}
u += dudx;
v += dvdx;
++dest;
}
u0 += dudy;
v0 += dvdy;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -