draw, How, directly, image, screen
The speed of image drawing is very important in game development, but the Symbian OS window frame does not offer full support for games. We need to access the screen buffer directly to provide fluent animation.
Display.h
class CDisplay : public MDirectScreenAccess
{
public:
static CDisplay*NewL( RWsSession& pClient, CWsScreenDevice& pScreenDevice, RWindow& pWindow );
static CDisplay*NewLC( RWsSession& pClient, CWsScreenDevice& pScreenDevice, RWindow& pWindow );
~CDisplay();
inline CWsScreenDevice& GetScreenDevice()
{
return m_pScreenDevice;
}
inline RWindow& GetWindow()
{
return m_pWindow;
}
inline CFbsBitGc* GetScreenGc()
{
return m_pGc;
}
void Start();
void Stop();
void Update();
private:
CDisplay( RWsSession& pClient, CWsScreenDevice& pScreenDevice, RWindow& pWindow );
void ConstructL();
void Restart( RDirectScreenAccess::TTerminationReasons aReason );
void AbortNow( RDirectScreenAccess::TTerminationReasons aReason );
private:
CWsScreenDevice& m_pScreenDevice;
RWsSession& m_pClient;
RWindow& m_pWindow;
CDirectScreenAccess* m_pDirectScreenAccess;
RRegion* m_pRegion;
CFbsBitGc* m_pGc;
TBool m_bDrawing;
};
Display.cpp
CDisplay* CDisplay::NewL( RWsSession& pClient, CWsScreenDevice& pScreenDevice, RWindow& pWindow )
{
CDisplay* self = NewLC( pClient, pScreenDevice, pWindow );
CleanupStack::Pop( self );
return self;
}
CDisplay* CDisplay::NewLC( RWsSession& pClient, CWsScreenDevice& pScreenDevice, RWindow& pWindow )
{
CDisplay* self = new ( ELeave ) CDisplay( pClient, pScreenDevice, pWindow );
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
CDisplay::CDisplay( RWsSession& pClient, CWsScreenDevice& pScreenDevice, RWindow& pWindow ) :
m_pClient( pClient ),
m_pScreenDevice( pScreenDevice ),
m_pWindow( pWindow )
{
m_pDirectScreenAccess = NULL;
m_pRegion = NULL;
m_pGc = NULL;
m_bDrawing = EFalse;
}
CDisplay::~CDisplay()
{
delete m_pDirectScreenAccess;
}
void CDisplay::ConstructL()
{
m_pDirectScreenAccess = CDirectScreenAccess::NewL( m_pClient, m_pScreenDevice, m_pWindow, *this );
}
void CDisplay::Start()
{
if( !m_bDrawing )
{
TRAPD( dsaErr, m_pDirectScreenAccess->StartL() );
if( dsaErr == KErrNone )
{
m_pGc = m_pDirectScreenAccess->Gc();
m_pRegion = m_pDirectScreenAccess->DrawingRegion();
m_pGc->SetClippingRegion( m_pRegion );
m_bDrawing = ETrue;
}
}
}
void CDisplay::Stop()
{
if( m_bDrawing )
{
m_bDrawing = EFalse;
}
}
void CDisplay::Update()
{
m_pDirectScreenAccess->ScreenDevice()->Update();
}
void CDisplay::Restart( RDirectScreenAccess::TTerminationReasons /*aReason*/ )
{
Start();
}
void CDisplay::AbortNow( RDirectScreenAccess::TTerminationReasons /*aReason*/ )
{
m_pDirectScreenAccess->Cancel();
m_bDrawing = EFalse;
}