cc68a136 |
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 |