switch Cyclone to submodule on it's own git repo
[picodrive.git] / platform / uiq2 / launcher / Engine.cpp
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