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

📄 example2dcontainer.cpp

📁 基于SYMBIAN OS,series 60平台的经典游戏,超级马力
💻 CPP
字号:
/*
* ============================================================================
*  Name     : CExample2DContainer from Example2DContainer.h
*  Part of  : Example2D
*  Created  : 23.09.2005 by 
*  Implementation notes:
*     Initial content was generated by Series 90 Application Wizard.
*  Version  :
*  Copyright: 
* ============================================================================
*/

// INCLUDE FILES
#include "Example2DContainer.h"
#include <eikenv.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 CExample2DContainer::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__) && defined(__SERIES60_30__)
	iBitmap.LockHeap();
#endif

	// create TBitmap mirror of iBitmap
	TRAPD(err, iBmScreen = CBitmap::NewL( (TUint16*)iBitmap.DataAddress(), 
										  iBitmap.SizeInPixels(), 
										  iBitmap.DisplayMode() ));
	
#if defined(__WINS__) && defined(__SERIES60_30__)
	iBitmap.UnlockHeap();
#endif

	User::LeaveIfError(err);

	iBmScreen->Clear( TRgb( 0,0,0 ) );
	//
	// Guess target phone
	//
	TSize s = iBmScreen->Size();
	if( ( s == TSize( 176, 208 ) ) || // orig. S60 resolution
			( s == TSize( 352, 416 ) ) || // double resolution
			( s == TSize( 416, 352 ) ) ||	// E70 in landscape mode
			( s == TSize( 320, 240 ) ) ||	// QVGA (E61)
			( s == TSize( 240, 320 ) ) )	// QVGA landscape (N71)
		{
		iPhone = ESeries60;
		}
	if( s == TSize( 640,200 ) )
		{
		iPhone = ESeries80;
		}	
	if( s == TSize( 640,320 ) )
		{
		iPhone = ESeries90;
		}
	if( iPhone == EUnknownDevice )
		{
		User::Leave( KErrNotSupported );
		}
	InitPhone();
	
	//
	// Window ordinal
	//
	iPos = CCoeEnv::Static()->RootWin().FullOrdinalPosition();

	//
	// Application path
	//
		
	TParse parse;
	iPath = CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
	#if defined(__WINS__) && !defined(__SERIES60_30__)
		parse.Set( _L("c:"), &iPath, NULL );
	#else
		parse.Set( iPath, NULL, NULL );
	#endif
	
	#ifdef __SERIES60_30__
	
	iPath = parse.Drive();
	iPath.Append(_L("\\private\\101ff1c4\\"));
	
	#else
	
	iPath = parse.DriveAndPath();
	
	#endif // __SERIES60_30__
	
    ActivateL();

	iForeGround = ETrue;


	//
	// Create models
	//
	iModel.Append( CModelTitle::NewL( this ) );
	iModel.Append( CModelGame::NewL( this ) );
	iModel.Append( CModelHelp::NewL( this ) );
	
	//
	// Select current model
	//
	iChangeModel = EFalse;

	iCurrentModel = iModel[ EModelTitleScreen ];
	iCurrentModel->ActivateL();

	iTiming = CTiming::NewL( this );
	
	LoadMusic();
	}



CExample2DContainer::~CExample2DContainer()
    {
	delete iTiming;
	delete iMusicData;

	iCurrentModel->Deactivate();
	iModel.ResetAndDestroy();
	delete iBmScreen;
	delete iAudio;
	iAudioSource.Reset();
	ControlEnv()->RemoveForegroundObserver( *this );
	}



TKeyResponse CExample2DContainer::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 CExample2DContainer::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
	//
	iTiming->Start();
	}



void CExample2DContainer::HandleLosingForeground()
	{
	iForeGround = EFalse;
	delete iAudio;
	iAudio = NULL;
	iTiming->Stop();
	}



void CExample2DContainer::Exit()
	{
	iEikonEnv->Static()->EikAppUi()->HandleCommandL( EEikCmdExit );
	}



void CExample2DContainer::ChangeModelL( TModel aModel )
	{
	iNextModel = aModel;
	iChangeModel = ETrue;
	}



TBool CExample2DContainer::KeyState( TInt aKey )
	{
	return iKeyState[ aKey ];
	}



const TFileName& CExample2DContainer::Path()
	{
	return iPath;
	}



void CExample2DContainer::AddAudio( const TDesC8& aAudio )
	{
	iAudioSource.Append( TAudioClip( aAudio ) );
	if( iAudio )
		{
		iAudio->SetAudioSource( this );
		}
	}

void CExample2DContainer::ToggleAudio()
	{
	// Toggle audio -> on -> off 
	if( iAudioState )
		{
		iAudioState = EFalse;
		}
	else
		{
		iAudioState = ETrue;
		}
	}


void CExample2DContainer::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();
	
#ifdef __SERIES60_30__
	TInt64 cnt64 = ( time.Int64() - iLastTime.Int64() ) * KMovePerSecond / 1000000;
	TUint cnt = (TUint)cnt64;
#else
	TUint cnt = ( ( time.Int64() - iLastTime.Int64() ) * KMovePerSecond / 1000000 ).Low();
#endif
	
	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__) && defined(__SERIES60_30__)
	iBitmap.LockHeap();
#endif

	iBmScreen->SetData( (TUint16*)iBitmap.DataAddress() );
	
#if defined(__WINS__) && defined(__SERIES60_30__)
	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 CExample2DContainer::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 CExample2DContainer::InitPhone()
	{
	switch( iPhone )
		{
		case ESeries60:
			{
			iExitKey = EStdKeyDevice1;
			iSelectKey = EStdKeyDevice0; 
			iOkKey = EStdKeyDevice3;
			iBackKey = EStdKeyDevice1;
			break;
			}
		case ESeries80:
			{
			iExitKey = EStdKeyEscape;
			iSelectKey = EStdKeyDevice0; 
			iOkKey = EStdKeyDeviceA;
			iBackKey = EStdKeyDevice3;
			break;
			}
		case ESeries90:
			{
			iExitKey = EStdKeyEscape;
			iSelectKey = EStdKeyDevice4;
			iOkKey = EStdKeyDevice7;
			iBackKey = EStdKeyDevice5;
			break;
			}
		default:
			break;
		}
	}



void CExample2DContainer::StartAudio()
	{
	iAudio = CAudio::NewL();
	iAudio->SetAudioSource( this );
	}



void CExample2DContainer::PrepareExit()
	{
	iExitFromModel = ETrue;
	}


	
TUint8 CExample2DContainer::ExitKey()
	{
	return iExitKey;
	}



TUint8 CExample2DContainer::SelectKey()
	{
	return iSelectKey;
	}



TUint8 CExample2DContainer::OkKey()
	{
	return iOkKey;
	}



TUint8 CExample2DContainer::BackKey() 
	{
	return iBackKey;
	}



void CExample2DContainer::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 CExample2DContainer::HandleScreenDeviceChanged()
	{
	// screen size or orientation has changed 
	// -> reset window size to full screen
	SetExtentToWholeScreen();

	// set new screen size + draw rect
	iBmScreen->SetSize(iBitmap.SizeInPixels());
	iBmScreen->SetDrawRect(iBmScreen->Size());	
	}
	
// End of file

⌨️ 快捷键说明

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