| 1 | /*******************************************************************\r |
| 2 | *\r |
| 3 | * File: Engine.cpp\r |
| 4 | *\r |
| 5 | * Author: Peter van Sebille (peter@yipton.net)\r |
| 6 | *\r |
| 7 | * Modified/adapted for picodriveN by notaz, 2006\r |
| 8 | *\r |
| 9 | * (c) Copyright 2006, notaz\r |
| 10 | * (c) Copyright 2002, Peter van Sebille\r |
| 11 | * All Rights Reserved\r |
| 12 | *\r |
| 13 | *******************************************************************/\r |
| 14 | \r |
| 15 | #include "Engine.h"\r |
| 16 | #include <w32std.h>\r |
| 17 | #include <eikenv.h>\r |
| 18 | //#include <eikdll.h>\r |
| 19 | \r |
| 20 | #include "../version.h"\r |
| 21 | \r |
| 22 | \r |
| 23 | CGameRunner::~CGameRunner()\r |
| 24 | {\r |
| 25 | Cancel();\r |
| 26 | \r |
| 27 | RProcess process;\r |
| 28 | if(process.Open(iProcessId) == KErrNone) {\r |
| 29 | process.Terminate(1);\r |
| 30 | process.Close();\r |
| 31 | }\r |
| 32 | }\r |
| 33 | \r |
| 34 | CGameRunner::CGameRunner(MGameWatcher& aGameWatcher)\r |
| 35 | : CActive(CActive::EPriorityStandard), iGameWatcher(aGameWatcher)\r |
| 36 | {\r |
| 37 | }\r |
| 38 | \r |
| 39 | \r |
| 40 | CGameRunner* CGameRunner::NewL(MGameWatcher& aGameWatcher)\r |
| 41 | {\r |
| 42 | CGameRunner* self = new(ELeave) CGameRunner(aGameWatcher);\r |
| 43 | CleanupStack::PushL(self);\r |
| 44 | self->ConstructL();\r |
| 45 | CleanupStack::Pop(); // self\r |
| 46 | return self;\r |
| 47 | }\r |
| 48 | \r |
| 49 | void CGameRunner::ConstructL()\r |
| 50 | {\r |
| 51 | RProcess newProcess, thisProcess;\r |
| 52 | \r |
| 53 | // make path to picosmall\r |
| 54 | TBuf<KMaxFileName> exePath;\r |
| 55 | TBuf<KMaxFileName*3> tmpbuff; // hopefully large enough\r |
| 56 | thisProcess.CommandLine(tmpbuff);\r |
| 57 | TInt pos = tmpbuff.Find(_L(" "));\r |
| 58 | if(pos == KErrNotFound) pos = tmpbuff.Length();\r |
| 59 | for(pos--; pos > 2; pos--)\r |
| 60 | if(tmpbuff[pos] == '\\') break;\r |
| 61 | if(pos > 2) {\r |
| 62 | exePath.Copy(tmpbuff.Ptr(), pos+1);\r |
| 63 | exePath.Append(_L("PICOSMALL.EXE"));\r |
| 64 | }\r |
| 65 | \r |
| 66 | DEBUGPRINT(_L("[app] starting EXE: %S"), &exePath);\r |
| 67 | if(newProcess.Create(exePath, _L(""))) {\r |
| 68 | CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to start emulation process."));\r |
| 69 | thisProcess.Terminate(1);\r |
| 70 | }\r |
| 71 | \r |
| 72 | iProcessId = newProcess.Id();\r |
| 73 | DEBUGPRINT(_L("[app] newProcess.Id(): %d"), iProcessId);\r |
| 74 | \r |
| 75 | CActiveScheduler::Add(this);\r |
| 76 | newProcess.SetOwner(thisProcess); // Warning: phone strangely reboots when attempting to get owner after thisProcess exits\r |
| 77 | newProcess.Logon(iStatus);\r |
| 78 | \r |
| 79 | SetActive();\r |
| 80 | \r |
| 81 | newProcess.Resume(); // start execution\r |
| 82 | newProcess.Close();\r |
| 83 | }\r |
| 84 | \r |
| 85 | void CGameRunner::RunL()\r |
| 86 | {\r |
| 87 | iGameWatcher.NotifyEmuDeath();\r |
| 88 | }\r |
| 89 | \r |
| 90 | void CGameRunner::DoCancel()\r |
| 91 | {\r |
| 92 | RProcess process;\r |
| 93 | if(process.Open(iProcessId) == KErrNone) {\r |
| 94 | process.LogonCancel(iStatus);\r |
| 95 | process.Close();\r |
| 96 | }\r |
| 97 | }\r |
| 98 | \r |
| 99 | \r |
| 100 | // CExitForcer\r |
| 101 | CExitForcer::~CExitForcer()\r |
| 102 | {\r |
| 103 | Cancel();\r |
| 104 | }\r |
| 105 | \r |
| 106 | CExitForcer::CExitForcer(MGameWatcher& aGameWatcher) : CActive(CActive::EPriorityStandard), iGameWatcher(aGameWatcher)\r |
| 107 | {\r |
| 108 | }\r |
| 109 | \r |
| 110 | \r |
| 111 | CExitForcer* CExitForcer::NewL(MGameWatcher& aGameWatcher, TInt ms)\r |
| 112 | {\r |
| 113 | CExitForcer* self = new(ELeave) CExitForcer(aGameWatcher);\r |
| 114 | CleanupStack::PushL(self);\r |
| 115 | self->ConstructL(ms);\r |
| 116 | CleanupStack::Pop(); // self\r |
| 117 | return self;\r |
| 118 | }\r |
| 119 | \r |
| 120 | void CExitForcer::ConstructL(TInt ms)\r |
| 121 | {\r |
| 122 | CActiveScheduler::Add(this);\r |
| 123 | iTimer.CreateLocal();\r |
| 124 | iTimer.After(iStatus, ms*1000);\r |
| 125 | SetActive();\r |
| 126 | }\r |
| 127 | \r |
| 128 | void CExitForcer::RunL()\r |
| 129 | {\r |
| 130 | iGameWatcher.NotifyForcedExit();\r |
| 131 | }\r |
| 132 | \r |
| 133 | void CExitForcer::DoCancel()\r |
| 134 | {\r |
| 135 | if(iTimer.Handle()) {\r |
| 136 | iTimer.Cancel();\r |
| 137 | iTimer.Close();\r |
| 138 | }\r |
| 139 | }\r |
| 140 | \r |
| 141 | \r |
| 142 | // CThreadWatcher\r |
| 143 | CThreadWatcher::~CThreadWatcher()\r |
| 144 | {\r |
| 145 | Cancel();\r |
| 146 | }\r |
| 147 | \r |
| 148 | CThreadWatcher::CThreadWatcher(MGameWatcher& aGameWatcher, const TDesC& aName)\r |
| 149 | : CActive(CActive::EPriorityStandard), iGameWatcher(aGameWatcher), iName(aName)\r |
| 150 | {\r |
| 151 | }\r |
| 152 | \r |
| 153 | \r |
| 154 | CThreadWatcher* CThreadWatcher::NewL(MGameWatcher& aGameWatcher, const TDesC& aName)\r |
| 155 | {\r |
| 156 | CThreadWatcher* self = new(ELeave) CThreadWatcher(aGameWatcher, aName);\r |
| 157 | CleanupStack::PushL(self);\r |
| 158 | self->ConstructL();\r |
| 159 | CleanupStack::Pop(); // self\r |
| 160 | return self;\r |
| 161 | }\r |
| 162 | \r |
| 163 | void CThreadWatcher::ConstructL()\r |
| 164 | {\r |
| 165 | CActiveScheduler::Add(this);\r |
| 166 | RThread thread;\r |
| 167 | if(thread.Open(iName) == KErrNone) {\r |
| 168 | thread.Logon(iStatus);\r |
| 169 | thread.Close();\r |
| 170 | SetActive();\r |
| 171 | }\r |
| 172 | }\r |
| 173 | \r |
| 174 | void CThreadWatcher::RunL()\r |
| 175 | {\r |
| 176 | iGameWatcher.NotifyEmuDeath();\r |
| 177 | }\r |
| 178 | \r |
| 179 | void CThreadWatcher::DoCancel()\r |
| 180 | {\r |
| 181 | RThread thread;\r |
| 182 | if(thread.Open(iName) == KErrNone) {\r |
| 183 | thread.LogonCancel(iStatus);\r |
| 184 | thread.Close();\r |
| 185 | }\r |
| 186 | }\r |
| 187 | \r |
| 188 | \r |
| 189 | // config\r |
| 190 | TPLauncherConfig::TPLauncherConfig(TPicoConfig &cfg)\r |
| 191 | : iEmuConfig(cfg)\r |
| 192 | {\r |
| 193 | iLastROMFile.Copy(_L("C:\\"));\r |
| 194 | \r |
| 195 | // ini\r |
| 196 | TBuf<KMaxFileName*3> tmpbuff; // hopefully large enough\r |
| 197 | RProcess me;\r |
| 198 | me.CommandLine(tmpbuff);\r |
| 199 | TInt pos = tmpbuff.Find(_L(" "));\r |
| 200 | if(pos == KErrNotFound) pos = tmpbuff.Length();\r |
| 201 | if(pos > 3) {\r |
| 202 | iIniFileName.Copy(tmpbuff.Ptr(), pos-3);\r |
| 203 | iIniFileName.Append(_L("ini"));\r |
| 204 | }\r |
| 205 | //DEBUGPRINT(_L("[app] made ini: %S"), &iIniFileName);\r |
| 206 | }\r |
| 207 | \r |
| 208 | \r |
| 209 | void TPLauncherConfig::Load()\r |
| 210 | {\r |
| 211 | RFile file;\r |
| 212 | \r |
| 213 | if(!file.Open(CEikonEnv::Static()->FsSession(), iIniFileName, 0))\r |
| 214 | {\r |
| 215 | TInt version;\r |
| 216 | TPckg<TInt> pkg_version(version);\r |
| 217 | TPckg<TBool> pkg_Pad(iPad);\r |
| 218 | TBuf8<KMaxFileName> pad0; // reserved for future use (6 words)\r |
| 219 | TPtr8 picoCfg((TUint8*) &iEmuConfig, sizeof(iEmuConfig));\r |
| 220 | \r |
| 221 | file.Read(pkg_version);\r |
| 222 | file.Read(pkg_Pad);\r |
| 223 | file.Read(pad0, 24);\r |
| 224 | file.Read(pad0, KMaxFileName);\r |
| 225 | file.Read(picoCfg);\r |
| 226 | \r |
| 227 | TBuf8<KMaxFileName> file8(pad0.Ptr()); // take as zero terminated string\r |
| 228 | iLastROMFile.Copy(file8);\r |
| 229 | //DEBUGPRINT(_L("[app] iLastROMFile (%i): %S"), iLastROMFile.Length(), &iLastROMFile);\r |
| 230 | \r |
| 231 | file.Close();\r |
| 232 | }\r |
| 233 | }\r |
| 234 | \r |
| 235 | void TPLauncherConfig::Save()\r |
| 236 | {\r |
| 237 | RFile file;\r |
| 238 | \r |
| 239 | if(!file.Replace(CEikonEnv::Static()->FsSession(), iIniFileName, EFileWrite)) {\r |
| 240 | TInt version = (KPicoMajorVersionNumber<<24)+(KPicoMinorVersionNumber<<16);\r |
| 241 | TPckgC<TInt> pkg_version(version);\r |
| 242 | TPckgC<TBool> pkg_Pad(iPad);\r |
| 243 | TBuf8<KMaxFileName> pad0; pad0.FillZ(KMaxFileName);\r |
| 244 | TBuf8<KMaxFileName> file8; file8.Copy(iLastROMFile);\r |
| 245 | TPtrC8 picoCfg((TUint8*) &iEmuConfig, sizeof(iEmuConfig));\r |
| 246 | \r |
| 247 | file.Write(pkg_version);\r |
| 248 | file.Write(pkg_Pad); // 0x0004\r |
| 249 | file.Write(pad0, 24); // 0x0008, reserved for future use (6 words)\r |
| 250 | file.Write(file8); // 0x0020\r |
| 251 | file.Write(pad0, KMaxFileName-file8.Length());\r |
| 252 | file.Write(picoCfg); // 0x0120\r |
| 253 | \r |
| 254 | file.Close();\r |
| 255 | }\r |
| 256 | }\r |