📄 mario2dcontainer.cpp
字号:
/*
============================================================================
* Name : CMario2DContainer.cpp
* Part of : 2DMario
* Description : Implementation of CMario2DContainer
* Copyright (c) 2007 Nokia Corporation
============================================================================
*/
// INCLUDE FILES
#include "Mario2DContainer.h"
#include <eikenv.h>
#include <APGCLI.H>
#include <APGTASK.H>
#include <MSVSTD.H>
#include <eikapp.h>
#include <eikappui.h>
#include "CBitmap.h"
#include "CModelTitle.h"
#include "CModelGame.h"
#include "CModelHelp.h"
#include "CTiming.h"
#include "CAudio.h"
const TUint KMovePerSecond = 320;
void CMario2DContainer::ConstructL( const TRect& /*aRect*/ )
{
ControlEnv()->AddForegroundObserverL( *this );
// create backed up window for this control
CreateBackedUpWindowL( CCoeEnv::Static()->RootWin() );
// and make the backup for whole window
BackedUpWindow().MaintainBackup();
// set full screen
SetExtentToWholeScreen();
// create a mirror of backup window's bitmap
// all drawing to this bitmap
TInt wh = BackedUpWindow().BitmapHandle();
iBitmap.Duplicate( wh );
// use LockHeap / UnlockHeap in emulator builds for S60 3rd Edition
// to avoid FBSCLI 22 panic when calling CFbsBitmap::DataAddress()
#if defined(__WINS__)
iBitmap.LockHeap();
#endif
// create TBitmap mirror of iBitmap
TRAPD(err, iBmScreen = CBitmap::NewL( (TUint16*)iBitmap.DataAddress(),
iBitmap.SizeInPixels(),
iBitmap.DisplayMode() ));
#if defined(__WINS__)
iBitmap.UnlockHeap();
#endif
User::LeaveIfError(err);
iBmScreen->Clear( TRgb( 0,0,0 ) );
//
// Guess target phone
//
TSize s = iBmScreen->Size();
InitPhone();
//
// Window ordinal
//
iPos = CCoeEnv::Static()->RootWin().FullOrdinalPosition();
//
// Application path
//
RFs fs;
User::LeaveIfError(fs.Connect());
fs.PrivatePath(iPath);
#ifndef __WINS__
TFileName appFullName = CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
TParse parse;
parse.Set( appFullName, NULL, NULL);
iPath.Insert(0, parse.Drive());
#endif
fs.Close();
ActivateL();
// Open MsvSession to get SMS notifications
iMsvSession = CMsvSession::OpenAsyncL(*this);
iForeGround = ETrue;
//
// Create models
//
iGameModel = CModelGame::NewL( this );
iModel.Append( CModelTitle::NewL( this ) );
iModel.Append( iGameModel );
iModel.Append( CModelHelp::NewL( this ) );
//
// Select current model
//
iChangeModel = EFalse;
iCurrentModel = iModel[ EModelTitleScreen ];
iCurrentModel->ActivateL();
iTiming = CTiming::NewL( this );
LoadMusic();
}
CMario2DContainer::~CMario2DContainer()
{
delete iTiming;
delete iMusicData;
delete iMsvEntry;
delete iMsvSession;
iCurrentModel->Deactivate();
iModel.ResetAndDestroy();
delete iBmScreen;
delete iAudio;
iAudioSource.Reset();
ControlEnv()->RemoveForegroundObserver( *this );
}
TKeyResponse CMario2DContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
{
TInt key = aKeyEvent.iScanCode;
if( aType == EEventKeyDown )
{
iKeyState[ key ] = 1;
}
if( aType == EEventKeyUp )
{
iKeyState[ key ] = 0;
}
return EKeyWasConsumed;
}
void CMario2DContainer::HandleGainingForeground()
{
iForeGround = ETrue;
//
// Some keys might have been left to down state
// Clear all key states
//
Mem::FillZ( iKeyState, 256 );
//
// Last update time
//
iLastTime.HomeTime();
//
// Window ordinal
//
iPos = CCoeEnv::Static()->RootWin().FullOrdinalPosition();
//
// Start audio
//
StartAudio();
//
// Start timing. Use a longer interval (100ms) for the first timer call,
// to give MMF some time to fully open the audio stream
//
iTiming->Start((TTimeIntervalMicroSeconds32)100000);
}
void CMario2DContainer::HandleLosingForeground()
{
iForeGround = EFalse;
delete iAudio;
iAudio = NULL;
iTiming->Stop();
}
void CMario2DContainer::Exit()
{
iEikonEnv->Static()->EikAppUi()->HandleCommandL( EEikCmdExit );
}
void CMario2DContainer::ChangeModelL( TModel aModel )
{
iNextModel = aModel;
iChangeModel = ETrue;
}
TBool CMario2DContainer::KeyState( TInt aKey )
{
return iKeyState[ aKey ];
}
const TFileName& CMario2DContainer::Path()
{
return iPath;
}
void CMario2DContainer::AddAudio( const TDesC8& aAudio )
{
iAudioSource.Append( TAudioClip( aAudio ) );
if( iAudio )
{
iAudio->SetAudioSource( this );
}
}
void CMario2DContainer::ToggleAudio()
{
// Toggle audio -> on -> off
if( iAudioState )
{
iAudioState = EFalse;
}
else
{
// give some extra cpu time to start audio
iAudioState = ETrue;
}
if ( iAudio )
iAudio->Mute(iAudioState);
}
void CMario2DContainer::TimingCall()
{
if( iExitFromModel )
{
Exit();
return;
}
if( iChangeModel )
{
//
// Some keys might have been left to down state
// Clear all key states
//
Mem::FillZ( iKeyState, 256 );
iCurrentModel->Deactivate();
iCurrentModel = iModel[ iNextModel ];
iCurrentModel->ActivateL();
iChangeModel = EFalse;
}
//
// Check audio problems
//
if( iAudio == NULL )
{
StartAudio();
}
else if( iAudio->Error() )
{
delete iAudio;
iAudio = NULL;
StartAudio();
}
TTime time;
time.HomeTime();
TInt64 cnt64 = ( time.Int64() - iLastTime.Int64() ) * KMovePerSecond / 1000000;
TUint cnt = (TUint)cnt64;
iLastTime = time;
// minimum 1 update
if( cnt < 1 ) cnt = 1;
// maximum of one second worth of updates
if( cnt > KMovePerSecond ) cnt = KMovePerSecond;
// do game update
TUint i;
for( i=0; i<cnt; i++ )
{
iCurrentModel->Move();
}
// Screen bitmap address can change
// so update pointers
TInt wh = BackedUpWindow().BitmapHandle();
iBitmap.Duplicate( wh );
TBitmapUtil bitmapUtil( &iBitmap );
bitmapUtil.Begin( TPoint( 0,0 ) );
// use LockHeap / UnlockHeap in emulator builds for S60 3rd Edition
// to avoid FBSCLI 22 panic when calling CFbsBitmap::DataAddress()
#if defined(__WINS__)
iBitmap.LockHeap();
#endif
iBmScreen->SetData( (TUint16*)iBitmap.DataAddress() );
#if defined(__WINS__)
iBitmap.UnlockHeap();
#endif
// do game draw
iCurrentModel->Draw( *iBmScreen );
bitmapUtil.End();
//
// draw buffer to screen
// first check if this window is still topmost
// change thread priority during these operations
// so the window cannot change ordinal position before actual copy to screen
//
RThread().SetPriority( EPriorityAbsoluteHigh );
TInt pos = CCoeEnv::Static()->RootWin().FullOrdinalPosition();
if( pos < iPos )
{
iPos = pos;
}
if( iForeGround && ( iPos == pos ) )
{
BackedUpWindow().UpdateScreen();
}
//
// Some phones have UI response difficulties with EPriorityNormal
//
RThread().SetPriority( EPriorityLess );
}
void CMario2DContainer::FillAudio( TInt16* aBuffer, TInt aLength )
{
Mem::FillZ( aBuffer, aLength * sizeof( TInt16 ) );
if( !iAudioState )
{
return;
}
TInt c = iAudioSource.Count();
TInt i;
for( i=0; i<c; i++ )
{
TInt8* p = (TInt8*)( iAudioSource[ i ].iData.Ptr() );
TInt l = iAudioSource[ i ].iData.Length();
TInt pos = iAudioSource[ i ].iPosition;
TInt x;
for( x=0; x<aLength; x++ )
{
aBuffer[ x ] += (p[ pos ] ) * 256; // 8-bit sample to 16-bit buffer
pos++;
if( pos == l )
{
pos = 0;
}
}
iAudioSource[ i ].iPosition = pos;
}
}
void CMario2DContainer::InitPhone()
{
iExitKey = EStdKeyDevice1;
iSelectKey = EStdKeyDevice0;
iOkKey = EStdKeyDevice3;
iBackKey = EStdKeyDevice1;
}
void CMario2DContainer::StartAudio()
{
TRAPD(err, iAudio = CAudio::NewL());
if (err == KErrNone)
{
iAudio->Mute(iAudioState);
iAudio->SetAudioSource( this );
}
}
void CMario2DContainer::PrepareExit()
{
iExitFromModel = ETrue;
}
TUint8 CMario2DContainer::ExitKey()
{
return iExitKey;
}
TUint8 CMario2DContainer::SelectKey()
{
return iSelectKey;
}
TUint8 CMario2DContainer::OkKey()
{
return iOkKey;
}
TUint8 CMario2DContainer::BackKey()
{
return iBackKey;
}
void CMario2DContainer::LoadMusic()
{
TFileName file;
file.Copy( Path() );
file.Append( _L("noname-8b.raw") );
RFs fs;
fs.Connect();
CleanupClosePushL( fs );
RFile f;
User::LeaveIfError( f.Open( fs, file, EFileRead ) );
CleanupClosePushL( f );
f.Size( iMusicLength );
iMusicData = new( ELeave )TUint8[ iMusicLength ];
TPtr8 loadPtr( iMusicData, iMusicLength );
f.Read( loadPtr );
// convert from unsigned samples to signed samples
for( TInt i=0; i<iMusicLength; i++ )
{
iMusicData[ i ] += 128;
}
CleanupStack::PopAndDestroy( 2 ); // f, fs
AddAudio( TPtrC8( iMusicData, iMusicLength ) );
}
void CMario2DContainer::HandleScreenDeviceChanged()
{
// screen size or orientation has changed
// -> reset window size to full screen
if (iCurrentModel != iGameModel)
{
iCurrentModel->Deactivate();
iCurrentModel->ActivateL();
}
SetExtentToWholeScreen();
// set new screen size + draw rect
iBmScreen->SetSize(iBitmap.SizeInPixels());
iBmScreen->SetDrawRect(iBmScreen->Size());
}
// check incoming messages and go to background if new sms is received
void CMario2DContainer::HandleSessionEventL(
MMsvSessionObserver::TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/)
{
switch (aEvent)
{
case EMsvServerReady:
// Initialise iMsvEntry
if (!iMsvEntry)
{
iMsvEntry = CMsvEntry::NewL(*iMsvSession, KObservedFolderId, TMsvSelectionOrdering());
}
break;
case EMsvEntriesCreated:
// Only look for changes in the Inbox
if (*(static_cast<TMsvId*>(aArg2)) == KObservedFolderId)
{
// msg received to inbox, go to background
TApaTaskList taskList(iEikonEnv->WsSession());
const TInt KIdleAppUID = 0x101FD64C;
TApaTask task = taskList.FindApp(TUid::Uid(KIdleAppUID));
task.BringToForeground();
}
break;
default:
break;
}
}
// End of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -