App.cpp 13 KB

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