proper timeout handling for input subsys
[picodrive.git] / platform / uiq3 / App.cpp
CommitLineData
cc68a136 1/*******************************************************************\r
2 *\r
3 * File: App.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
ca482e5d 15#include "App.h"\r
cc68a136 16// #include "picodriven.mbg" // bitmap identifiers\r
ca482e5d 17#include "rsc/picodrive.rsg" // resource include\r
cc68a136 18#include <eikenv.h>\r
19#include <qbtselectdlg.h>\r
20//#include <gulutil.h>\r
21//#include <bautils.h>\r
22//#include <eikmenub.h> // CEikMenuBar\r
23#include <apgtask.h> // TApaSystemEvent\r
24#include <eikstart.h>\r
25#include <eikedwin.h>\r
26#include <s32strm.h>\r
27\r
ca482e5d 28#include <qikappui.h>\r
29#include <qikeditcategoryobserver.h>\r
30#include <qikselectfiledlg.h>\r
31#include <qikcommand.h>\r
cc68a136 32\r
33#include "Dialogs.h"\r
34#include "engine/debug.h"\r
ca482e5d 35#include "../common/emu.h"\r
36#include "emu.h"\r
cc68a136 37\r
f8af9634 38extern "C" char menuErrorMsg[];\r
cc68a136 39\r
40////////////////////////////////////////////////////////////////\r
41//\r
42// class CPicolAppView\r
43//\r
44////////////////////////////////////////////////////////////////\r
45\r
46// Creates and constructs the view.\r
47CPicolAppView* CPicolAppView::NewLC(CQikAppUi& aAppUi, TPicoConfig& aCurrentConfig)\r
48{\r
49 CPicolAppView* self = new (ELeave) CPicolAppView(aAppUi, aCurrentConfig);\r
50 CleanupStack::PushL(self);\r
51 return self;\r
52}\r
53\r
54/**\r
55Constructor for the view.\r
56Passes the application UI reference to the construction of the super class.\r
57\r
58KNullViewId should normally be passed as parent view for the applications \r
59default view. The parent view is the logical view that is normally activated \r
60when a go back command is issued. KNullViewId will activate the system \r
61default view. \r
62\r
63@param aAppUi Reference to the application UI\r
64*/\r
65CPicolAppView::CPicolAppView(CQikAppUi& aAppUi, TPicoConfig& aCurrentConfig) \r
66: CQikViewBase(aAppUi, KNullViewId), iCurrentConfig(aCurrentConfig)\r
67{\r
68}\r
69\r
70void CPicolAppView::ConstructL()\r
71{\r
72 BaseConstructL();\r
73}\r
74\r
75CPicolAppView::~CPicolAppView()\r
76{\r
77}\r
78\r
79\r
80/**\r
81Inherited from CQikViewBase and called upon by the UI Framework. \r
82It creates the view from resource.\r
83*/\r
84void CPicolAppView::ViewConstructL()\r
85{\r
86 // Loads information about the UI configurations this view supports\r
87 // together with definition of each view. \r
88 ViewConstructFromResourceL(R_APP_UI_CONFIGURATIONS);\r
89 UpdateCommandList();\r
90}\r
91\r
92/**\r
93Returns the view Id\r
94\r
95@return Returns the Uid of the view\r
96*/\r
97TVwsViewId CPicolAppView::ViewId()const\r
98{\r
99 return TVwsViewId(KUidPicolApp, KUidPicolMainView);\r
100}\r
101\r
102/**\r
103Handles all commands in the view.\r
104Called by the UI framework when a command has been issued.\r
105The command Ids are defined in the .hrh file.\r
106\r
107@param aCommand The command to be executed\r
108@see CQikViewBase::HandleCommandL\r
109*/\r
110void CPicolAppView::HandleCommandL(CQikCommand& aCommand)\r
111{\r
112 TInt res;\r
113\r
114 switch(aCommand.Id())\r
115 {\r
116 case EEikCmdPicoLoadState:\r
117 if(iROMLoaded) {\r
118 CEikonEnv::Static()->BusyMsgL(_L("Loading State"));\r
119 res = CPicoGameSession::Do(PicoMsgLoadState);\r
120 CEikonEnv::Static()->BusyMsgCancel();\r
121 // emu doesn't start to run if load fails, so we can display this\r
122 if(res) CEikonEnv::Static()->InfoMsg(_L("Load Failed"));\r
123 }\r
124 break;\r
125\r
126 case EEikCmdPicoSaveState:\r
127 if(iROMLoaded) {\r
128 CEikonEnv::Static()->BusyMsgL(_L("Saving State"));\r
129 res = CPicoGameSession::Do(PicoMsgSaveState);\r
130 CEikonEnv::Static()->BusyMsgCancel();\r
131 if(res) CEikonEnv::Static()->InfoMsg(_L("Save Failed"));\r
132 }\r
133 break;\r
134\r
135 case EEikCmdPicoLoadROM:\r
136 DisplayOpenROMDialogL();\r
137 DEBUGPRINT(_L("after DisplayOpenROMDialogL()"));\r
138 break;\r
139\r
140 case EEikCmdPicoResume:\r
141 CPicoGameSession::Do(PicoMsgResume);\r
142 break;\r
143\r
144 case EEikCmdPicoReset:\r
145 CPicoGameSession::Do(PicoMsgReset);\r
146 break;\r
147\r
148 case EEikCmdPicoSettings:\r
149 DisplayConfigDialogL();\r
150 break;\r
151\r
152 case EEikCmdHelpAbout:\r
153 DisplayAboutDialogL();\r
154 break;\r
155\r
156 case EEikCmdPicoDebugInfo:\r
157 DisplayDebugDialogL();\r
158 break;\r
159\r
160 case EEikCmdPicoKeys:\r
161 CPicoGameSession::Do(PicoMsgConfigChange, &iCurrentConfig);\r
162 CPicoGameSession::Do(PicoMsgKeys);\r
163 break;\r
164\r
165 case EEikCmdPicoFrameskipAuto:\r
ca482e5d 166 currentConfig.Frameskip = -1;\r
167 emu_WriteConfig(0);\r
cc68a136 168 break;\r
169\r
170 case EEikCmdPicoFrameskip0:\r
ca482e5d 171 currentConfig.Frameskip = 0;\r
172 emu_WriteConfig(0);\r
cc68a136 173 break;\r
174\r
175 case EEikCmdPicoFrameskip1:\r
ca482e5d 176 currentConfig.Frameskip = 1;\r
177 emu_WriteConfig(0);\r
cc68a136 178 break;\r
179\r
180 case EEikCmdPicoFrameskip2:\r
ca482e5d 181 currentConfig.Frameskip = 2;\r
182 emu_WriteConfig(0);\r
cc68a136 183 break;\r
184\r
185 case EEikCmdPicoFrameskip4:\r
ca482e5d 186 currentConfig.Frameskip = 4;\r
187 emu_WriteConfig(0);\r
cc68a136 188 break;\r
189\r
190 case EEikCmdPicoFrameskip8:\r
ca482e5d 191 currentConfig.Frameskip = 8;\r
192 emu_WriteConfig(0);\r
cc68a136 193 break;\r
194\r
195 case EEikCmdExit:\r
ca482e5d 196 emu_Deinit();\r
cc68a136 197 CPicoGameSession::freeResources();\r
198 //break; // this is intentional\r
199\r
200 default:\r
201 // Go back and exit command will be passed to the CQikViewBase to handle.\r
202 CQikViewBase::HandleCommandL(aCommand);\r
203 break;\r
204 }\r
205}\r
206\r
207void CPicolAppView::DisplayOpenROMDialogL()\r
208{\r
209 // Array of mimetypes that the dialog shall filter on, if empty all\r
210 // mimetypes will be visible.\r
211 CDesCArray* mimeArray = new (ELeave) CDesCArrayFlat(1);\r
212 CleanupStack::PushL(mimeArray);\r
213 // Array that will be filled with the file paths that are choosen\r
214 // from the dialog. \r
215 CDesCArray* fileArray = new (ELeave) CDesCArraySeg(3);\r
216 CleanupStack::PushL(fileArray);\r
217 _LIT16(KDlgTitle, "Select a ROM file");\r
218\r
713c9224 219 TPtrC8 text8((TUint8*) rom_fname_loaded);\r
ca482e5d 220 iCurrentConfig.iLastROMFile.Copy(text8);\r
221\r
cc68a136 222 if( CQikSelectFileDlg::RunDlgLD( *mimeArray, *fileArray, &KDlgTitle, &iCurrentConfig.iLastROMFile) )\r
223 {\r
224 CEikonEnv::Static()->BusyMsgL(_L("Loading ROM"));\r
225 TPtrC16 file = (*fileArray)[0];\r
ca482e5d 226 //iCurrentConfig.iLastROMFile.Copy(file);\r
cc68a136 227\r
228 // push the config first\r
229 CPicoGameSession::Do(PicoMsgSetAppView, this);\r
230 CPicoGameSession::Do(PicoMsgConfigChange, &iCurrentConfig);\r
231\r
232 TInt res = CPicoGameSession::Do(PicoMsgLoadROM, &file);\r
233\r
234 CEikonEnv::Static()->BusyMsgCancel();\r
235\r
236 iROMLoaded = EFalse;\r
237 switch (res)\r
238 {\r
f8af9634 239 case PicoErrRomOpenFailed: {\r
240 TBuf<64> mErrorBuff;\r
241 TPtrC8 buff8((TUint8*) menuErrorMsg);\r
242 mErrorBuff.Copy(buff8);\r
243 CEikonEnv::Static()->InfoWinL(_L("Error"), mErrorBuff);\r
cc68a136 244 break;\r
f8af9634 245 }\r
cc68a136 246\r
247 case PicoErrOutOfMem:\r
248 CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to allocate memory."));\r
249 break;\r
250\r
cc68a136 251 case PicoErrEmuThread:\r
252 CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to create emulation thread. Try to restart this application."));\r
253 break;\r
254\r
255 default:\r
256 iROMLoaded = ETrue;\r
257 break;\r
258 }\r
259\r
260 // errors which leave ROM loaded\r
261 switch (res)\r
262 {\r
263 case PicoErrOutOfMemSnd:\r
264 CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to allocate sound buffer, disabled sound."));\r
265 break;\r
266\r
267 case PicoErrGenSnd:\r
268 CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to start soundsystem, disabled sound."));\r
269 break;\r
270 }\r
ca482e5d 271 if(res == 6 || res == 7) currentConfig.EmuOpt &= ~EOPT_EN_SOUND;\r
cc68a136 272\r
273 if(iROMLoaded) {\r
274 if(iTitleAdded)\r
275 ViewContext()->ChangeTextL(EEikCidTitleBarLabel, CPicoGameSession::iRomInternalName);\r
276 else ViewContext()->AddTextL (EEikCidTitleBarLabel, CPicoGameSession::iRomInternalName);\r
277 iTitleAdded = ETrue;\r
278 UpdateCommandList();\r
279 }\r
280 }\r
281 CleanupStack::PopAndDestroy(2, mimeArray);\r
282}\r
283\r
284\r
285void CPicolAppView::DisplayConfigDialogL()\r
286{\r
ca482e5d 287 CPicoConfigDialog* configDialog = new(ELeave)CPicoConfigDialog(currentConfig);\r
288 emu_packConfig();\r
cc68a136 289 configDialog->ExecuteLD(R_PICO_CONFIG);\r
ca482e5d 290 emu_unpackConfig();\r
291 emu_WriteConfig(0);\r
cc68a136 292\r
ca482e5d 293 CPicoGameSession::Do(PicoMsgConfigChange, &currentConfig);\r
cc68a136 294}\r
295\r
296\r
297void CPicolAppView::DisplayAboutDialogL()\r
298{\r
299 TInt iButtonRes;\r
300 CAboutDialog* dialog = new (ELeave) CAboutDialog;\r
301\r
302 dialog->PrepareLC(R_PICO_ABOUT);\r
303 iButtonRes = dialog->RunLD();\r
304\r
305 if(iButtonRes == EEikCmdPicoAboutCreditsCmd) {\r
306 CCreditsDialog *creditsDialog = new (ELeave) CCreditsDialog();\r
307 creditsDialog->PrepareLC(R_PICO_CREDITS);\r
308 creditsDialog->RunLD();\r
309 }\r
310}\r
311\r
312#ifdef __DEBUG_PRINT\r
ca482e5d 313extern "C" char *PDebugMain();\r
cc68a136 314#endif\r
315\r
316void CPicolAppView::DisplayDebugDialogL()\r
317{\r
318#ifdef __DEBUG_PRINT\r
ca482e5d 319 CDebugDialog* dialog = new (ELeave) CDebugDialog(PDebugMain());\r
cc68a136 320\r
321 dialog->PrepareLC(R_PICO_DEBUG);\r
322 dialog->RunLD();\r
323#endif\r
324}\r
325\r
326void CPicolAppView::UpdateCommandList()\r
327{\r
328 CQikCommandManager& commandManager = CQikCommandManager::Static(*iCoeEnv);\r
329 CQikCommand *cmd_fs[10];\r
330 Mem::FillZ(cmd_fs, sizeof(CQikCommand*)*10);\r
331\r
332 CQikCommand* cmd_reset = commandManager.Command(*this, EEikCmdPicoReset);\r
333 CQikCommand* cmd_savest = commandManager.Command(*this, EEikCmdPicoSaveState);\r
334 CQikCommand* cmd_loadst = commandManager.Command(*this, EEikCmdPicoLoadState);\r
335 CQikCommand* cmd_resume = commandManager.Command(*this, EEikCmdPicoResume);\r
336 cmd_fs[0] = commandManager.Command(*this, EEikCmdPicoFrameskipAuto);\r
337 cmd_fs[1] = commandManager.Command(*this, EEikCmdPicoFrameskip0);\r
338 cmd_fs[2] = commandManager.Command(*this, EEikCmdPicoFrameskip1);\r
339 cmd_fs[3] = commandManager.Command(*this, EEikCmdPicoFrameskip2);\r
340 cmd_fs[5] = commandManager.Command(*this, EEikCmdPicoFrameskip4);\r
341 cmd_fs[9] = commandManager.Command(*this, EEikCmdPicoFrameskip8);\r
342\r
343 TBool dimmed = !CPicoGameSession::iEmuRunning || !iROMLoaded;\r
344 cmd_reset ->SetDimmed(dimmed);\r
345 cmd_savest->SetDimmed(dimmed);\r
346 cmd_loadst->SetDimmed(dimmed);\r
347 cmd_resume->SetDimmed(dimmed);\r
348\r
349 // frameskip\r
ca482e5d 350 TInt fs_index = currentConfig.Frameskip + 1;\r
cc68a136 351 if (fs_index >= 0 && fs_index < 10 && cmd_fs[fs_index])\r
352 {\r
353 cmd_fs[fs_index]->SetChecked(ETrue);\r
354 }\r
355}\r
356\r
357\r
358////////////////////////////////////////////////////////////////\r
359//\r
360// class CPicolAppUi\r
361//\r
362////////////////////////////////////////////////////////////////\r
363\r
364\r
365void CPicolAppUi::ConstructL()\r
366{\r
367 BaseConstructL();\r
368\r
369 // Create the view and add it to the framework\r
370 iAppView = CPicolAppView::NewLC(*this, ((CPicolDocument *)Document())->iCurrentConfig);\r
371 AddViewL(*iAppView);\r
372 CleanupStack::Pop(iAppView);\r
373}\r
374\r
375\r
376////////////////////////////////////////////////////////////////\r
377//\r
378// CPicolDocument\r
379//\r
380////////////////////////////////////////////////////////////////\r
381\r
382\r
383CPicolDocument::CPicolDocument(CQikApplication& aApp)\r
384: CQikDocument(aApp)\r
385{\r
cc68a136 386}\r
387\r
388CQikAppUi* CPicolDocument::CreateAppUiL()\r
389{\r
390 return new(ELeave) CPicolAppUi;\r
391}\r
392\r
393/**\r
394Called by the framework when ::SaveL has been called.\r
395*/\r
396void CPicolDocument::StoreL(CStreamStore& aStore, CStreamDictionary& aStreamDic) const\r
397{\r
ca482e5d 398#if 0\r
cc68a136 399 RStoreWriteStream stream;\r
400\r
401 TStreamId preferenceId = stream.CreateLC(aStore);\r
402 aStreamDic.AssignL(KUidPicolStore, preferenceId);\r
403\r
404 // Externalize preference\r
405 stream << iCurrentConfig;\r
406\r
407 // Ensures that any buffered data is written to aStore\r
408 stream.CommitL();\r
409 CleanupStack::PopAndDestroy(); // stream\r
ca482e5d 410#endif\r
cc68a136 411/*\r
412 // tmp\r
413 TInt res;\r
414 RFile logFile;\r
415 res = logFile.Replace(CEikonEnv::Static()->FsSession(), _L("C:\\Shared\\pico.cfg"), EFileWrite|EFileShareAny);\r
416 if(!res) {\r
417 logFile.Write(TPtr8((TUint8 *)&iCurrentConfig, sizeof(iCurrentConfig), sizeof(iCurrentConfig)));\r
418 logFile.Close();\r
419 }\r
420*/\r
421}\r
422\r
423/**\r
424Called by the framework on application start.\r
425Loads the application data from disk, i.e. domain data and preferences.\r
426*/\r
427void CPicolDocument::RestoreL(const CStreamStore& aStore, const CStreamDictionary& aStreamDic)\r
428{ \r
ca482e5d 429#if 0\r
cc68a136 430 // Find the stream ID of the model data from the stream dictionary:\r
431 TStreamId preferenceId(aStreamDic.At(KUidPicolStore));\r
432 RStoreReadStream stream;\r
433 stream.OpenLC(aStore, preferenceId);\r
434 if(preferenceId != KNullStreamId)\r
435 {\r
436 // Interalize preference and model\r
437 stream >> iCurrentConfig;\r
438 }\r
439\r
440 CleanupStack::PopAndDestroy(); // stream\r
ca482e5d 441#endif\r
cc68a136 442\r
443 // tmp\r
444/* TInt res;\r
445 RFile logFile;\r
446 res = logFile.Open(CEikonEnv::Static()->FsSession(), _L("C:\\Shared\\pico.cfg"), EFileRead|EFileShareAny);\r
447 if(!res) {\r
448 TPtr8 ptr((TUint8 *)&iCurrentConfig, sizeof(iCurrentConfig), sizeof(iCurrentConfig));\r
449 logFile.Read(ptr);\r
450 logFile.Close();\r
451 }*/\r
452}\r
453\r
454////////////////////////////////////////////////////////////////\r
455//\r
456// framework\r
457//\r
458////////////////////////////////////////////////////////////////\r
459\r
460\r
461CApaDocument* CPicolApplication::CreateDocumentL()\r
462{\r
463 return new (ELeave) CPicolDocument(*this);\r
464}\r
465\r
466EXPORT_C CApaApplication* NewApplication()\r
467{\r
468 return new CPicolApplication;\r
469}\r
470\r
471\r
472TUid CPicolApplication::AppDllUid() const\r
473{\r
474 return KUidPicolApp;\r
475}\r
476\r
477\r
ca482e5d 478extern "C" TInt my_SetExceptionHandler(TInt, TExceptionHandler, TUint32);\r
479\r
cc68a136 480GLDEF_C TInt E32Main()\r
481{\r
ca482e5d 482 // doesn't work :(\r
cc68a136 483 User::SetExceptionHandler(ExceptionHandler, (TUint32) -1);\r
ca482e5d 484// my_SetExceptionHandler(KCurrentThreadHandle, ExceptionHandler, 0xffffffff);\r
485\r
486 emu_Init();\r
cc68a136 487\r
488 return EikStart::RunApplication(NewApplication);\r
489}\r
490\r
491\r