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