00001
00002
00003
00004
00005
00006
00007
00008
00009
00013
00014
00015 #include <e32std.h>
00016 #include "CGameFramework.h"
00017 #include "CGame.h"
00018 #include "TGamePanics.h"
00019
00020
00025 CGameFramework* CGameFramework::NewL(){
00026 CGameFramework* self= new (ELeave) CGameFramework;
00027 return(self);
00028 };
00029
00031 CGameFramework::~CGameFramework() {
00032 delete iLevel;
00033 delete iMap;
00034 };
00035
00041 void CGameFramework::CancelL() {
00042 iData.iKeys |= TGameData::EQuit;
00043 RunL(EFalse);
00044 }
00045
00061 TInt CGameFramework::GameThread(TAny* aGameData) {
00062
00063 CTrapCleanup* cleanup=CTrapCleanup::New();
00064 if(cleanup==NULL)
00065 return KErrNoMemory;
00066
00067 TInt error=KErrNone;
00068
00069 TGameData& data= (*STATIC_CAST(TGameData*,aGameData));
00070
00071
00072
00073 while(data.iLives!=0 && !(data.iKeys & TGameData::EQuit) &&
00074 data.iLevelCompleted==EFalse && error==KErrNone) {
00075
00076 CGame *game=NULL;
00077 TRAPD(error,game=CGame::NewL(data));
00078 if(error==KErrNone) {
00079 game->Play();
00080 delete game;
00081 }
00082 }
00083 delete cleanup;
00084 return error;
00085 };
00086
00088 TInt CGameFramework::Score() {
00089 return(iData.iScore);
00090 }
00091
00092
00106 CGameFramework::TGameState CGameFramework::RunL(TBool aReset) {
00107
00108
00109 __ASSERT_ALWAYS(iLevel!=NULL && iMap!=NULL,TGamePanics::Panic(TGamePanics::ENoLevelLoaded));
00110
00111
00112 if(aReset!=EFalse) {
00113 iData.iLives=3;
00114 iData.iScore=0;
00115 }
00116
00117
00118 RWsSession winSession;
00119 User::LeaveIfError(winSession.Connect());
00120 CleanupClosePushL(winSession);
00121
00122
00123
00124
00125 const TUint32 KWindowHandle=1;
00126 const TUint32 KWindowGroupHandle=2;
00127
00128
00129 RWindowGroup winGroup(winSession);
00130 User::LeaveIfError(winGroup.Construct(KWindowGroupHandle));
00131 CleanupClosePushL(winGroup);
00132
00133
00134
00135
00136 RBlankWindow window(winSession);
00137 User::LeaveIfError(window.Construct(winGroup,KWindowHandle));
00138 CleanupClosePushL(window);
00139 window.Activate();
00140 window.SetSize(TSize(640,200));
00141
00142
00143
00144 window.EnableFocusChangeEvents();
00145
00146
00147 iData.iForceRedraw=ETrue;
00148
00149
00150 iGameThread.Logon(iGameStatus);
00151 iGameThread.Resume();
00152
00153
00154 TBool finished=Play(winSession);
00155
00156
00157 winSession.EventReadyCancel();
00158
00159 iGameThread.LogonCancel(iGameStatus);
00160
00161
00162 User::WaitForAnyRequest();
00163
00164
00165 CleanupStack::PopAndDestroy(3,&winSession);
00166
00167
00168 if(finished==EFalse) {
00169
00170 User::WaitForAnyRequest();
00171
00172 return EPaused;
00173 } else {
00174
00175 iGameThread.Close();
00176 delete iLevel;
00177 iLevel=NULL;
00178 delete iMap;
00179 iMap=NULL;
00180
00181 User::Heap().Compress();
00182
00183
00184 if(iData.iLevelCompleted==EFalse) {
00185 return EDied;
00186 } else {
00187 return ELevelCompleted;
00188 }
00189 }
00190 };
00191
00192
00210 TBool CGameFramework::Play(RWsSession &aWindSession) {
00211 TRequestStatus normalEvent;
00212
00213
00214 aWindSession.EventReady(&normalEvent);
00215
00216 for(;;) {
00217 User::WaitForAnyRequest();
00218 if(normalEvent!=KRequestPending) {
00219 TWsEvent event;
00220 aWindSession.GetEvent(event);
00221 aWindSession.EventReady(&normalEvent);
00222 switch(event.Type()) {
00223 case EEventKeyDown: {
00224 TKeyEvent *key=event.Key();
00225 switch(key->iScanCode) {
00226 case EStdKeyLeftArrow: iData.iKeys |= TGameData::ELeft; break;
00227 case EStdKeyRightArrow: iData.iKeys |= TGameData::ERight; break;
00228 case EStdKeyUpArrow: iData.iKeys |= TGameData::EUp; break;
00229 case EStdKeyDownArrow: iData.iKeys |= TGameData::EDown; break;
00230 case 'Q': iData.iKeys |= TGameData::EQuit; break;
00231 case 'A': iData.iKeys |= TGameData::EAction1; break;
00232 case EStdKeySpace: iData.iKeys |= TGameData::EAction2; break;
00233 case EStdKeyLeftShift: iData.iKeys |= TGameData::EAction3; break;
00234 case EStdKeyEnter: iData.iKeys |= TGameData::EAction4; break;
00235 case 'P': {
00236 iGameThread.Suspend();
00237 return EFalse;
00238 }
00239 }
00240 }
00241 break;
00242 case EEventKeyUp: {
00243 TKeyEvent *key=event.Key();
00244 switch(key->iScanCode) {
00245 case EStdKeyLeftArrow: iData.iKeys &= ~TGameData::ELeft; break;
00246 case EStdKeyRightArrow: iData.iKeys &= ~TGameData::ERight; break;
00247 case EStdKeyUpArrow: iData.iKeys &= ~TGameData::EUp; break;
00248 case EStdKeyDownArrow: iData.iKeys &= ~TGameData::EDown; break;
00249 case 'A': iData.iKeys &= ~TGameData::EAction1; break;
00250 case EStdKeySpace: iData.iKeys &= ~TGameData::EAction2; break;
00251 case EStdKeyLeftShift: iData.iKeys &= ~TGameData::EAction3; break;
00252 case EStdKeyEnter: iData.iKeys &= ~TGameData::EAction4; break;
00253 }
00254 }
00255 break;
00256 case EEventFocusLost:
00257
00258 iGameThread.Suspend();
00259 return EFalse;
00260 break;
00261 }
00262 } else if(iGameStatus!=KRequestPending) {
00263
00264 return ETrue;
00265 } else {
00266
00267
00268 CActiveScheduler *sched=CActiveScheduler::Current();
00269 if(sched!=NULL) {
00270 TInt error;
00271 sched->RunIfReady(error,0);
00272 }
00273 }
00274 }
00275 }
00276
00289 void CGameFramework::LoadLevelL(const TDesC& aLevelName,const TDesC& aMapName, TBool aResetShip) {
00290 __ASSERT_ALWAYS(iLevel==NULL && iMap==NULL,TGamePanics::Panic(TGamePanics::ELoadLevelWithLevelLoaded));
00291
00292 RFs fs;
00293 User::LeaveIfError(fs.Connect());
00294 CleanupClosePushL(fs);
00295
00296
00297
00298 RFile levelFile;
00299 User::LeaveIfError(levelFile.Open(fs,aLevelName,EFileRead));
00300 CleanupClosePushL(levelFile);
00301
00302 TInt size;
00303 User::LeaveIfError(levelFile.Size(size));
00304 size-=16;
00305 HBufC8 *levelDes= HBufC8::NewLC(size);
00306 TPtr8 levelPtr=levelDes->Des();
00307 User::LeaveIfError(levelFile.Read(16,levelPtr,size));
00308
00309
00310
00311 RFile mapFile;
00312 User::LeaveIfError(mapFile.Open(fs,aMapName,EFileRead));
00313 CleanupClosePushL(mapFile);
00314
00315 User::LeaveIfError(mapFile.Size(size));
00316 size-=16;
00317 HBufC8 *mapDes= HBufC8::NewLC(size);
00318 TPtr8 mapPtr=mapDes->Des();
00319 User::LeaveIfError(mapFile.Read(16,mapPtr,size));
00320
00321
00322
00323
00324
00325 _LIT(KGameThread,"RealGame");
00326
00327 const TInt KStackSize=4*1024;
00328
00329
00330 User::LeaveIfError(iGameThread.Create(KGameThread,GameThread,KStackSize,NULL,&iData));
00331
00332
00333 iGameThread.SetPriority(EPriorityLess);
00334
00335
00336
00337
00338
00339 CleanupStack::Pop(mapDes);
00340 iMap=mapDes;
00341 CleanupStack::PopAndDestroy(&mapFile);
00342 CleanupStack::Pop(levelDes);
00343 iLevel=levelDes;
00344 CleanupStack::PopAndDestroy(2,&fs);
00345
00346
00347
00348 TInt32* level= (TInt32*) (iLevel->Ptr());
00349 TInt32* map= (TInt32*) (iMap->Ptr());
00350
00351 iData.iKeys=0;
00352 iData.iLevelCompleted=EFalse;
00353
00354 iData.iLevel.iMapData=(TInt16*) (iMap->Ptr()+map[0]);
00355 iData.iLevel.iPaths=(TInt16*) (iMap->Ptr()+map[1]);
00356
00357 iData.iLevel.iBackgrounds=(TUint16*) (iLevel->Ptr()+level[0]);
00358 iData.iLevel.iSprites=(TUint16*) (iLevel->Ptr()+level[1]);
00359 iData.iLevel.iStatus=(TUint16*) (iLevel->Ptr()+level[2]);
00360
00361 iData.iLevel.iShipSprite=(TInt16) map[2];
00362 iData.iLevel.iShipDeathStartSprite=(TInt16) map[3];
00363 iData.iLevel.iShipDeathEndSprite=(TInt16) map[4];
00364 iData.iLevel.iBadGuyDeathStartSprite=(TInt16) map[5];
00365 iData.iLevel.iBadGuyDeathEndSprite=(TInt16) map[6];
00366 iData.iLevel.iBulletPower1_StartSprite=(TInt16) map[7];
00367 iData.iLevel.iBulletPower2_StartSprite=(TInt16) map[8];
00368 iData.iLevel.iBulletPower3_StartSprite=(TInt16) map[9];
00369 iData.iLevel.iBulletPower4_StartSprite=(TInt16) map[10];
00370 iData.iLevel.iShipStartXPos=(TInt16) map[11];
00371 iData.iLevel.iShipStartYPos=(TInt16) map[12];
00372 iData.iLevel.iShipStartHealth=(TInt16) map[13];
00373 if(aResetShip!=EFalse) {
00374 iData.iLevel.iShipPowerups=(TInt16) map[14];
00375 }
00376 }
00377