⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cbitmap.cpp

📁 Symbian OS S60平台2D游戏引擎案例
💻 CPP
字号:
   /*
============================================================================
    * Name : CBitmap.cpp
    * Part of : 2DExample
    * Description : Implementation of CBitmap
    * Copyright (c) 2007 Nokia Corporation
============================================================================
    */

// INCLUDE FILES
#include <BitmapTransforms.h>
#include "CBitmap.h"
#include "Fbs.h"
#include <W32STD.H>
#include <EIKENV.H>

const TInt	KColor16MU = 11; // EColor16MU is not defined in earlier SDK's

CBitmap* CBitmap::NewL( const TSize& aSize )
	{
	CBitmap* bmp = new( ELeave )CBitmap;
    CleanupStack::PushL(bmp);
    bmp->ConstructL(aSize);
    CleanupStack::Pop();
	return bmp;
	}

CBitmap* CBitmap::NewL( TUint16* aData, const TSize& aSize, TDisplayMode aMode )
	{
	CBitmap* bmp = new( ELeave )CBitmap;
    CleanupStack::PushL(bmp);
    bmp->ConstructL(aData, aSize, aMode);
    CleanupStack::Pop();
	return bmp;
	}

CBitmap* CBitmap::NewL( const TFileName& aFileName, TInt aIndex, TBool aScale )
	{
	CBitmap* bmp = new( ELeave )CBitmap;
    CleanupStack::PushL(bmp);
    bmp->ConstructL(aFileName, aIndex, aScale);	
    CleanupStack::Pop();
	return bmp;	
	}

void CBitmap::ConstructL( const TSize& aSize )
    {
 	CActiveScheduler::Add(this);
	iSize = aSize;
	iDrawRect = aSize;
	iData = new( ELeave ) TUint16[ aSize.iWidth * aSize.iHeight ];
	iMode = EColor4K;
	Mem::FillZ( iData, aSize.iWidth * aSize.iHeight );
    }

void CBitmap::ConstructL( TUint16* aData, const TSize& aSize, TDisplayMode aMode )
    {
 	CActiveScheduler::Add(this);
	iSize = aSize;
	iDrawRect = aSize;
	iData = aData;
	iMode = aMode;
    }

void CBitmap::ConstructL( const TFileName& aFileName, TInt aIndex, TBool aScale )
    {
 	CActiveScheduler::Add(this);
    CFbsBitmap tmpBitmap;
	//load the correct bitmap..
	TInt ret;

    ret = tmpBitmap.Load( aFileName, aIndex );
	
	if( ret == KErrNone )
		{
        if (aScale)
            {
            Scale(tmpBitmap);
            }
		iSize = tmpBitmap.SizeInPixels ();
		iDrawRect = iSize;
		iData = new( ELeave ) TUint16[ iSize.iWidth * iSize.iHeight ];
		iMode = tmpBitmap.DisplayMode();

		TUint16* dst = ( TUint16* )iData;
		for ( TInt y=0; y<iSize.iHeight; y++ )
			{
			TPtr8 buf( ( TUint8* )dst, iSize.iWidth*2 );
			tmpBitmap.GetScanLine( buf, TPoint( 0, y ), iSize.iWidth, EColor4K );
			dst += iSize.iWidth;
			}

		tmpBitmap.Reset();
		}
	else
		{
		// file could not be loaded..
		// return a empty bitmap..
		iSize = TSize ( 0, 0 );
		iData = NULL;
		}
    }

void CBitmap::Scale( CFbsBitmap& aBitmap )
    {
    TSize bmSize = aBitmap.SizeInPixels();
    TPixelsTwipsAndRotation pixTwipsRot;
    CCoeEnv::Static()->ScreenDevice()->GetDefaultScreenSizeAndRotation(pixTwipsRot);
    TSize screensize = pixTwipsRot.iPixelSize;

    TInt newWidth = screensize.iWidth;
    TInt newHeight = screensize.iHeight;
    TBool after = ETrue;
    if (screensize.iWidth>bmSize.iWidth)
        {
        after = EFalse;
        newWidth = screensize.iWidth*screensize.iWidth/bmSize.iWidth;
        }
    if (screensize.iHeight>bmSize.iHeight)
        {
        newHeight = screensize.iHeight*screensize.iHeight/bmSize.iHeight;
        }
    if (!after)
        aBitmap.Resize(screensize);

    TSize newSize(newWidth, newHeight);
    CFbsBitmapDevice* bitDev = CFbsBitmapDevice::NewL(&aBitmap);
    CBitmapContext* bgc = NULL;
    bitDev->CreateBitmapContext(bgc);
    bgc->DrawBitmap(TRect(TPoint(0,0), newSize), &aBitmap);
    delete bgc;
    delete bitDev;
    if (after)
        aBitmap.Resize(screensize);
    
    }

void CBitmap::RunL()
	{
    if (iState == EScaling)
        {
    	iWait.AsyncStop();
        iState = EIdle;
        }
	}

void CBitmap::DoCancel()
	{	
	if(iData)
		delete iData;
	iData = NULL;
	}

CBitmap::~CBitmap()
	{
    Cancel();
    }



CBitmap::CBitmap() : CActive(CActive::EPriorityStandard)
	{
	}



void CBitmap::Destroy()
	{
	delete iData;
	iData = NULL;
	iSize = TSize( 0,0 );
	}



TSize CBitmap::Size()
	{
	return iSize;
	}
	
void CBitmap::SetSize(const TSize& aSize)
	{
	iSize = aSize;
	}



TUint16* CBitmap::Data()
	{
	return iData;
	}



void CBitmap::SetData( TUint16* aData )
	{
	iData = aData;
	}



void CBitmap::Draw( CBitmap& aTarget, const TPoint& aPosition )
	{
	//
	// Supports only 4096 color bitmaps, target can be 64K and 16M color aswell
	//
	if( iMode != EColor4K )
		{
		return;
		}

	TUint16* sp = (TUint16*)iData;
	
	TSize tsize = aTarget.Size();

	TSize drawSize = iDrawRect.Size();
	TPoint drawPos = iDrawRect.iTl;

	TInt w = drawSize.iWidth;
	TInt h = drawSize.iHeight;
	TInt x = aPosition.iX;
	TInt y = aPosition.iY;
	TInt sx = drawPos.iX;
	TInt sy = drawPos.iY;

	//
	// Clip
	//
	if( x < 0 )
		{
		w += x;
		sx -= x;
		x = 0;
		}
	if( y < 0 )
		{
		h += y;
		sy -= y;
		y = 0;
		}
	if( x + w >= tsize.iWidth )
		{
		w = tsize.iWidth - x;
		}
	if( y + h >= tsize.iHeight )
		{
		h = tsize.iHeight - y;
		}

	//
	// If clipped away, just return
	//
	if( w <= 0 )
		{
		return;
		};
	if( h <= 0 )
		{
		return;
		};

	//
	// Add source offset to source pointer
	//
	sp += sx;
	sp += sy * iSize.iWidth;


	//
	// Calculate modulo ( how much add pointers between horizontal lines )
	//
	TInt smod = iSize.iWidth - w;
	TInt tmod = tsize.iWidth - w;

	TInt tMode = aTarget.Mode();

	//
	// Select draw mode by target bitmap color mode and draw.
	//
	switch( tMode )
		{
		case EColor4K:
			{
			TUint16* tp = (TUint16*)aTarget.Data();
			tp += x;
			tp += y * tsize.iWidth;

			for( TInt yy=0; yy<h; yy++ )
				{
				for( TInt xx=0; xx<w; xx++ )
					{
					TUint16 c = *sp++;
					if( c != iMaskColor )
						{
						*tp = c;
						}
					tp++;
					}
				tp += tmod;
				sp += smod;
				}
			break;
			}

		case EColor64K:
			{
			TUint16* tp = (TUint16*)aTarget.Data();
			tp += x;
			tp += y * tsize.iWidth;

			for( TInt yy=0; yy<h; yy++ )
				{
				for( TInt xx=0; xx<w; xx++ )
					{
					TUint16 c = *sp++;
					if( c != iMaskColor )
						{
						// 0000rrrrggggbbbb -> rrrr0gggg00bbbb0 ( 4K to 64K color )
						*tp = (TUint16) ( ( ( c & 0xf00 ) << 4 ) + ( ( c & 0x0f0 ) << 3 ) + ( ( c & 0x00f ) << 1 ) );
						}
					tp++;
					}
				tp += tmod;
				sp += smod;
				}
			break;
			}

		case KColor16MU: 
			{
			TUint32* tp = (TUint32*)aTarget.Data();
			tp += x;
			tp += y * tsize.iWidth;

			for( TInt yy=0; yy<h; yy++ )
				{
				for( TInt xx=0; xx<w; xx++ )
					{
					TUint16 c = *sp++;
					if( c != iMaskColor )
						{
						// 0000rrrrggggbbbb -> rrrr0000gggg0000bbbb0000 ( 4K to 16M color )
						*tp = ( ( c & 0xf00 ) << 12 ) + ( ( c & 0x0f0 ) << 8 ) + ( ( c & 0x00f ) << 4 );
						}
					tp++;
					}
				tp += tmod;
				sp += smod;
				}
			break;
			}


		default:
			{
			// some unsupported color mode
			break;
			}
		}
	}



TDisplayMode CBitmap::Mode()
	{
	return iMode;
	}



TUint16 CBitmap::MaskColor()
	{
	return iMaskColor;
	}



void CBitmap::SetMaskColor( TUint16 aColor )
	{
	iMaskColor = aColor;
	}



TRect CBitmap::DrawRect()
	{
	return iDrawRect;
	}



void CBitmap::SetDrawRect( const TRect& aRect )
	{
	iDrawRect = aRect;
	}



void CBitmap::Clear( TRgb aRgb )
	{
	TInt longwords = iSize.iWidth * iSize.iHeight / 2;
	TUint32 longword = 0;

	switch( iMode )
		{
		case EColor4K:
			{
			longword = aRgb.Color4K();
			longword |= longword << 16;
			break;
			}
		case EColor64K:
			{
			longword = aRgb.Color64K();
			longword |= longword << 16;
			break;
			}
		default:
			{
			longword = aRgb.Color16M();
			longwords *= 2;
			break;
			}
		}

	TUint32* p = (TUint32*)iData;
	TInt i;
	for( i=0; i<longwords; i++ )
		{
		*p++ = longword;
		}
	}

// End of file

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -