📄 dirscraccrenderer.cpp
字号:
/*
* ============================================================================
* Name : CDirScrAccRenderer from DirScrAccRenderer.h
* Part of : DirScrAcc
* Created : 06/11/2003 by Forum Nokia
* Description:
* Renderer class creating a flying flag effect.
* Version :
* Copyright: Nokia Corporation
* ============================================================================
*/
#include <fbs.h> // for CFbsBitmap
#include "DirScrAccRenderer.h"
#include <eikenv.h> // for CEikonEnv::InfoMsg
static const TUint8 sinTable[256] =
{8, 8, 8, 8, 8, 8, 9, 9,
9, 9, 9, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 11, 12, 12,
12, 12, 12, 12, 13, 13, 13, 13,
13, 13, 13, 14, 14, 14, 14, 14,
14, 14, 14, 14, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 14, 14, 14,
14, 14, 14, 14, 14, 14, 13, 13,
13, 13, 13, 13, 13, 12, 12, 12,
12, 12, 12, 11, 11, 11, 11, 11,
11, 10, 10, 10, 10, 10, 9, 9,
9, 9, 9, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 7, 7,
7, 7, 7, 6, 6, 6, 6, 6,
5, 5, 5, 5, 5, 5, 4, 4,
4, 4, 4, 4, 3, 3, 3, 3,
3, 3, 3, 2, 2, 2, 2, 2,
2, 2, 2, 2, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3,
3, 3, 3, 3, 3, 4, 4, 4,
4, 4, 4, 5, 5, 5, 5, 5,
5, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 8, 8, 8, 8, 8};
#define MAX_OFFSET 15
_LIT(KBitmapFilename, "c:\\system\\apps\\DirScrAcc\\imagedata.mbm");
const TUint16 KMMCDriveLetter = 'e';
const TUint16 KROMDriveLetter = 'z';
//
// class CFlagRenderer
//
// ---------------------------------------------------------
// CFlagRenderer::CFlagRenderer()
// Contructor (private)
// ---------------------------------------------------------
CFlagRenderer::CFlagRenderer(TInt aWidth, TInt aHeight)
: iWidth(aWidth),
iHeight(aHeight),
iFrame(0)
{
iLength = aWidth * aHeight;
iScanLineLen = aWidth * 2;
}
// ---------------------------------------------------------
// CFlagRenderer::NewL()
// static method for instantiating a new CFlagRenderer
// ---------------------------------------------------------
CFlagRenderer* CFlagRenderer::NewL(TInt aWidth, TInt aHeight)
{
CFlagRenderer* self = new (ELeave) CFlagRenderer(aWidth, aHeight);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
// ---------------------------------------------------------
// CFlagRenderer::ConstructL()
// Symbian 2nd phase constructor (private)
// ---------------------------------------------------------
void CFlagRenderer::ConstructL()
{
// decide if we need to load normal or fullscreen bitmap
TInt useFullScreen = (iHeight == 208) ? 1 : 0;
// create a bitmap and load an image into it
// image color depth must be 12 bit
iImageFlag = new (ELeave) CFbsBitmap();
// try 3 locations - application directory in C,E (memory card), and Z drive
TFileName imageLocation(KBitmapFilename);
TInt loadErr = iImageFlag->Load(imageLocation,useFullScreen);
// not found on C, try E & Z
if(loadErr != KErrNone)
{
imageLocation[0] = KMMCDriveLetter;
loadErr = iImageFlag->Load(imageLocation,useFullScreen);
if(loadErr != KErrNone)
{
imageLocation[0] = KROMDriveLetter; // in emulator, apps usually reside on z
loadErr = iImageFlag->Load(imageLocation,useFullScreen);
}
}
// not found, display error message and leave
if(loadErr != KErrNone)
{
// InfoMsg only has effect in emulator
CEikonEnv::Static()->InfoMsg(_L("imagedata.mbm not found"));
// wait a while for the msg to show, then leave
User::After(1000000);
User::Leave(loadErr);
}
}
// ---------------------------------------------------------
// CFlagRenderer::~CFlagRenderer()
// Destructor
// ---------------------------------------------------------
CFlagRenderer::~CFlagRenderer()
{
delete iImageFlag;
iImageFlag = 0;
}
// ---------------------------------------------------------
// CFlagRenderer::RenderNextFrameL()
// Renders the next frame of the waving flag to a buffer
// specified by aBitmapAddr parameter
//
// Return value: TInt - index of the last rendered frame
// ---------------------------------------------------------
TInt CFlagRenderer::RenderNextFrameL(TUint8* aBitmapAddr)
{
// fetch an address for our flag image data
iFlagDataAddr = (TUint8*)iImageFlag->DataAddress();
// clear the target buffer
Mem::FillZ(aBitmapAddr, iLength << 1);
TInt angle = iFrame;
// horizontal scan: move scanlines to new locations according to sinTable
// MAX_OFFSET number of bottom scanlines are reserved for vertical shift, skip these
for(TInt s = 0; s < iHeight-MAX_OFFSET-1; s++)
{
Mem::Copy(aBitmapAddr + (s * iScanLineLen) + sinTable[angle % 256] * 2,
iFlagDataAddr + (s * iScanLineLen), iScanLineLen);
// store the offset for each scanline (to 4 bits not used for RGB data)
*(aBitmapAddr + (s * iScanLineLen) + 1) = static_cast<TUint8>((sinTable[angle % 256]) << 4);
// calculate a new speed for scanning through sinTable
angle += WaveSpeed(iFrame + s);
}
// vertical scan: move each pixel to new location according to sinTable
// and adjust pixel brightness
for(TInt i = 1; i < iWidth-1; i++)
{
for(TInt j = iHeight-MAX_OFFSET-2; j ; j--)
{
TUint16* orgLocation = (TUint16*)aBitmapAddr + j*iWidth + i;
TUint16* movLocation = orgLocation + (sinTable[angle % 256] * iWidth);
// get the offset stored in horizontal scan phase and calculate an average of hz/vt offsets
TUint8 hzOffset = static_cast<TUint8>(*(aBitmapAddr + ((j * iScanLineLen) + 1)) >> 4);
TInt avgOffset = ((sinTable[angle % 256] + hzOffset) >> 2);
if(orgLocation != movLocation)
{
// use the avg. offset to dim the pixels
TInt8 r = static_cast<TInt8>((*orgLocation & 0x00f) - avgOffset);
TInt8 g = static_cast<TInt8>(((*orgLocation & 0x0f0) >> 4) - avgOffset);
TInt8 b = static_cast<TInt8>(((*orgLocation & 0xf00) >> 8) - avgOffset);
// copy the pixel data to a new location
(r < 0) ? *movLocation = 0 : *movLocation = r;
(g < 0) ? *movLocation &= 0xf0f : *movLocation |= g << 4;
(b < 0) ? *movLocation &= 0x0ff : *movLocation |= b << 8;
// zero the original pixel
*orgLocation = 0;
}
}
// calculate a new speed for scanning through sinTable
angle += WaveSpeed(iFrame + i + 70);
}
return iFrame++;
}
inline TInt CFlagRenderer::WaveSpeed(TInt aIndex)
{
TInt waveSpeed = (aIndex & 0xe0) >> 5;
return (waveSpeed > 4) ? 9 - waveSpeed : waveSpeed + 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -