/******************************************************************* * * File: Engine.cpp * * Author: Peter van Sebille (peter@yipton.net) * * Modified/adapted for picodriveN by notaz, 2006 * * (c) Copyright 2006, notaz * (c) Copyright 2002, Peter van Sebille * All Rights Reserved * *******************************************************************/ #include "Engine.h" #include #include //#include #include "../version.h" CGameRunner::~CGameRunner() { Cancel(); RProcess process; if(process.Open(iProcessId) == KErrNone) { process.Terminate(1); process.Close(); } } CGameRunner::CGameRunner(MGameWatcher& aGameWatcher) : CActive(CActive::EPriorityStandard), iGameWatcher(aGameWatcher) { } CGameRunner* CGameRunner::NewL(MGameWatcher& aGameWatcher) { CGameRunner* self = new(ELeave) CGameRunner(aGameWatcher); CleanupStack::PushL(self); self->ConstructL(); CleanupStack::Pop(); // self return self; } void CGameRunner::ConstructL() { RProcess newProcess, thisProcess; // make path to picosmall TBuf exePath; TBuf tmpbuff; // hopefully large enough thisProcess.CommandLine(tmpbuff); TInt pos = tmpbuff.Find(_L(" ")); if(pos == KErrNotFound) pos = tmpbuff.Length(); for(pos--; pos > 2; pos--) if(tmpbuff[pos] == '\\') break; if(pos > 2) { exePath.Copy(tmpbuff.Ptr(), pos+1); exePath.Append(_L("PICOSMALL.EXE")); } DEBUGPRINT(_L("[app] starting EXE: %S"), &exePath); if(newProcess.Create(exePath, _L(""))) { CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to start emulation process.")); thisProcess.Terminate(1); } iProcessId = newProcess.Id(); DEBUGPRINT(_L("[app] newProcess.Id(): %d"), iProcessId); CActiveScheduler::Add(this); newProcess.SetOwner(thisProcess); // Warning: phone strangely reboots when attempting to get owner after thisProcess exits newProcess.Logon(iStatus); SetActive(); newProcess.Resume(); // start execution newProcess.Close(); } void CGameRunner::RunL() { iGameWatcher.NotifyEmuDeath(); } void CGameRunner::DoCancel() { RProcess process; if(process.Open(iProcessId) == KErrNone) { process.LogonCancel(iStatus); process.Close(); } } // CExitForcer CExitForcer::~CExitForcer() { Cancel(); } CExitForcer::CExitForcer(MGameWatcher& aGameWatcher) : CActive(CActive::EPriorityStandard), iGameWatcher(aGameWatcher) { } CExitForcer* CExitForcer::NewL(MGameWatcher& aGameWatcher, TInt ms) { CExitForcer* self = new(ELeave) CExitForcer(aGameWatcher); CleanupStack::PushL(self); self->ConstructL(ms); CleanupStack::Pop(); // self return self; } void CExitForcer::ConstructL(TInt ms) { CActiveScheduler::Add(this); iTimer.CreateLocal(); iTimer.After(iStatus, ms*1000); SetActive(); } void CExitForcer::RunL() { iGameWatcher.NotifyForcedExit(); } void CExitForcer::DoCancel() { if(iTimer.Handle()) { iTimer.Cancel(); iTimer.Close(); } } // CThreadWatcher CThreadWatcher::~CThreadWatcher() { Cancel(); } CThreadWatcher::CThreadWatcher(MGameWatcher& aGameWatcher, const TDesC& aName) : CActive(CActive::EPriorityStandard), iGameWatcher(aGameWatcher), iName(aName) { } CThreadWatcher* CThreadWatcher::NewL(MGameWatcher& aGameWatcher, const TDesC& aName) { CThreadWatcher* self = new(ELeave) CThreadWatcher(aGameWatcher, aName); CleanupStack::PushL(self); self->ConstructL(); CleanupStack::Pop(); // self return self; } void CThreadWatcher::ConstructL() { CActiveScheduler::Add(this); RThread thread; if(thread.Open(iName) == KErrNone) { thread.Logon(iStatus); thread.Close(); SetActive(); } } void CThreadWatcher::RunL() { iGameWatcher.NotifyEmuDeath(); } void CThreadWatcher::DoCancel() { RThread thread; if(thread.Open(iName) == KErrNone) { thread.LogonCancel(iStatus); thread.Close(); } } // config TPLauncherConfig::TPLauncherConfig(TPicoConfig &cfg) : iEmuConfig(cfg) { iLastROMFile.Copy(_L("C:\\")); // ini TBuf tmpbuff; // hopefully large enough RProcess me; me.CommandLine(tmpbuff); TInt pos = tmpbuff.Find(_L(" ")); if(pos == KErrNotFound) pos = tmpbuff.Length(); if(pos > 3) { iIniFileName.Copy(tmpbuff.Ptr(), pos-3); iIniFileName.Append(_L("ini")); } //DEBUGPRINT(_L("[app] made ini: %S"), &iIniFileName); } void TPLauncherConfig::Load() { RFile file; if(!file.Open(CEikonEnv::Static()->FsSession(), iIniFileName, 0)) { TInt version; TPckg pkg_version(version); TPckg pkg_Pad(iPad); TBuf8 pad0; // reserved for future use (6 words) TPtr8 picoCfg((TUint8*) &iEmuConfig, sizeof(iEmuConfig)); file.Read(pkg_version); file.Read(pkg_Pad); file.Read(pad0, 24); file.Read(pad0, KMaxFileName); file.Read(picoCfg); TBuf8 file8(pad0.Ptr()); // take as zero terminated string iLastROMFile.Copy(file8); //DEBUGPRINT(_L("[app] iLastROMFile (%i): %S"), iLastROMFile.Length(), &iLastROMFile); file.Close(); } } void TPLauncherConfig::Save() { RFile file; if(!file.Replace(CEikonEnv::Static()->FsSession(), iIniFileName, EFileWrite)) { TInt version = (KPicoMajorVersionNumber<<24)+(KPicoMinorVersionNumber<<16); TPckgC pkg_version(version); TPckgC pkg_Pad(iPad); TBuf8 pad0; pad0.FillZ(KMaxFileName); TBuf8 file8; file8.Copy(iLastROMFile); TPtrC8 picoCfg((TUint8*) &iEmuConfig, sizeof(iEmuConfig)); file.Write(pkg_version); file.Write(pkg_Pad); // 0x0004 file.Write(pad0, 24); // 0x0008, reserved for future use (6 words) file.Write(file8); // 0x0020 file.Write(pad0, KMaxFileName-file8.Length()); file.Write(picoCfg); // 0x0120 file.Close(); } }