PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/source/mupen64launcher/src/cselector.cpp

https://github.com/notaz/mupen64plus-pandora
C++ | 2678 lines | 2291 code | 284 blank | 103 comment | 522 complexity | 06c0ec8b69bad6d99a5ac29ad332b597 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-3.0, GPL-3.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /**
  2. * @section LICENSE
  3. *
  4. * PickleLauncher
  5. * Copyright (C) 2010-2011 Scott Smith
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. * @section LOCATION
  21. */
  22. #include "cselector.h"
  23. CSelector::CSelector() : CBase(),
  24. Redraw (true),
  25. SkipFrame (false),
  26. Rescan (true),
  27. RefreshList (true),
  28. SetOneEntryValue (false),
  29. SetAllEntryValue (false),
  30. TextScrollDir (true),
  31. ExtractAllFiles (false),
  32. DrawState_Title (true),
  33. DrawState_About (true),
  34. DrawState_Filter (true),
  35. DrawState_FilePath (true),
  36. DrawState_Index (true),
  37. DrawState_ZipMode (true),
  38. DrawState_Preview (true),
  39. DrawState_ButtonL (true),
  40. DrawState_ButtonR (true),
  41. Mode (MODE_SELECT_ENTRY),
  42. LastSelectedEntry (0),
  43. TextScrollOffset (0),
  44. CurScrollSpeed (0),
  45. CurScrollPause (0),
  46. ListNameHeight (0),
  47. FramesDrawn (0),
  48. FramesSkipped (0),
  49. FramesSleep (0),
  50. #if defined(DEBUG)
  51. FPSDrawn (0),
  52. FPSSkip (0),
  53. FPSSleep (0),
  54. FrameCountTime (0),
  55. LoopTimeAverage (0),
  56. #endif
  57. FrameEndTime (0),
  58. FrameStartTime (0),
  59. FrameDelay (0),
  60. Mouse (),
  61. Joystick (NULL),
  62. Screen (NULL),
  63. ImageBackground (NULL),
  64. ImagePointer (NULL),
  65. ImageSelectPointer (NULL),
  66. ImagePreview (NULL),
  67. ImageTitle (NULL),
  68. ImageAbout (NULL),
  69. ImageFilePath (NULL),
  70. ImageFilter (NULL),
  71. ImageIndex (NULL),
  72. ImageZipMode (NULL),
  73. #if defined(DEBUG)
  74. ImageDebug (NULL),
  75. #endif
  76. ImageButtons (),
  77. Fonts (),
  78. Config (),
  79. Profile (),
  80. System (),
  81. ConfigPath (DEF_CONFIG),
  82. ProfilePath (DEF_PROFILE),
  83. ZipListPath (DEF_ZIPLIST),
  84. EventReleased (),
  85. EventPressCount (),
  86. ButtonModesLeft (),
  87. ButtonModesRight (),
  88. DisplayList (),
  89. LabelButtons (),
  90. ListNames (),
  91. ItemsEntry (),
  92. ItemsArgument (),
  93. ItemsValue (),
  94. ItemsDefPlugin (),
  95. WhichPlugin (0),
  96. ItemsRomOption (),
  97. ItemsRomPlugin (),
  98. WhichRomPlugin (0),
  99. RectEntries (),
  100. RectButtonsLeft (),
  101. RectButtonsRight (),
  102. ScreenRectsDirty ()
  103. {
  104. Fonts.resize( FONT_SIZE_TOTAL, NULL );
  105. ButtonModesLeft.resize( BUTTONS_MAX_LEFT );
  106. ButtonModesRight.resize( BUTTONS_MAX_RIGHT );
  107. RectButtonsLeft.resize( BUTTONS_MAX_LEFT );
  108. RectButtonsRight.resize( BUTTONS_MAX_RIGHT );
  109. ImageButtons.resize( EVENT_TOTAL, NULL );
  110. LabelButtons.resize( EVENT_TOTAL, "" );
  111. LabelButtons.at(EVENT_ONE_UP) = BUTTON_LABEL_ONE_UP;
  112. LabelButtons.at(EVENT_ONE_DOWN) = BUTTON_LABEL_ONE_DOWN;
  113. LabelButtons.at(EVENT_PAGE_UP) = BUTTON_LABEL_PAGE_UP;
  114. LabelButtons.at(EVENT_PAGE_DOWN) = BUTTON_LABEL_PAGE_DOWN;
  115. LabelButtons.at(EVENT_DIR_UP) = BUTTON_LABEL_DIR_UP;
  116. LabelButtons.at(EVENT_DIR_DOWN) = BUTTON_LABEL_DIR_DOWN;
  117. LabelButtons.at(EVENT_ZIP_MODE) = BUTTON_LABEL_ZIP_MODE;
  118. LabelButtons.at(EVENT_CFG_APP) = BUTTON_LABEL_CONFIG;
  119. LabelButtons.at(EVENT_CFG_ITEM) = BUTTON_LABEL_EDIT;
  120. LabelButtons.at(EVENT_SET_ONE) = BUTTON_LABEL_SET_ONE;
  121. LabelButtons.at(EVENT_SET_ALL) = BUTTON_LABEL_SET_ALL;
  122. LabelButtons.at(EVENT_BACK) = BUTTON_LABEL_BACK;
  123. LabelButtons.at(EVENT_SELECT) = BUTTON_LABEL_SELECT;
  124. LabelButtons.at(EVENT_QUIT) = BUTTON_LABEL_QUIT;
  125. DisplayList.resize( MODE_TOTAL );
  126. EventPressCount.resize( EVENT_TOTAL, EVENT_LOOPS_OFF );
  127. EventReleased.resize( EVENT_TOTAL, false );
  128. }
  129. CSelector::~CSelector()
  130. {
  131. }
  132. int8_t CSelector::Run( int32_t argc, char** argv )
  133. {
  134. int8_t result;
  135. int16_t selection;
  136. result = 0;
  137. ProcessArguments( argc, argv );
  138. System.SetCPUClock( Config.CPUClock );
  139. // Load video,input,profile resources
  140. if (OpenResources())
  141. {
  142. result = 1;
  143. }
  144. // Display and poll the user for a selection
  145. if (result == 0)
  146. {
  147. selection = DisplayScreen();
  148. // Setup a exec script for execution following termination of this application
  149. if (selection >= 0)
  150. {
  151. if (RunExec( selection ))
  152. {
  153. result = 1;
  154. }
  155. }
  156. else if (selection < -1)
  157. {
  158. result = 1;
  159. }
  160. else
  161. {
  162. result = 0;
  163. }
  164. }
  165. // Release resources
  166. CloseResources( result );
  167. return result;
  168. }
  169. void CSelector::ProcessArguments( int argc, char** argv )
  170. {
  171. uint8_t arg_index;
  172. string launcher;
  173. string argument;
  174. launcher = string(argv[0]);
  175. Profile.LauncherName = launcher.substr( launcher.find_last_of('/')+1 );
  176. Profile.LauncherPath = launcher.substr( 0, launcher.find_last_of('/')+1 );
  177. if (Profile.LauncherPath.compare("./") == 0 || Profile.LauncherPath.length() == 0)
  178. {
  179. Profile.LauncherPath = string(getenv("PWD"))+"/";
  180. }
  181. #if defined(DEBUG)
  182. Log( "Running from '%s'\n", launcher.c_str() );
  183. #endif
  184. Log( "Running from '%s' as '%s'\n", Profile.LauncherPath.c_str(), Profile.LauncherName.c_str() );
  185. for (arg_index=0; arg_index<argc; arg_index++ )
  186. {
  187. argument = string(argv[arg_index]);
  188. if (argument.compare( ARG_RESETGUI ) == 0)
  189. {
  190. Config.ResetGUI = true;
  191. }
  192. else
  193. if (argument.compare( ARG_PROFILE ) == 0)
  194. {
  195. ProfilePath = string(argv[++arg_index]);
  196. }
  197. else
  198. if (argument.compare( ARG_CONFIG ) == 0)
  199. {
  200. ConfigPath = string(argv[++arg_index]);
  201. }
  202. else
  203. if (argument.compare( ARG_ZIPLIST ) == 0)
  204. {
  205. ZipListPath = string(argv[++arg_index]);
  206. }
  207. }
  208. }
  209. int8_t CSelector::OpenResources( void )
  210. {
  211. uint8_t button_index;
  212. uint32_t flags;
  213. string text;
  214. Log( "Loading config.\n" );
  215. if (Config.Load( ConfigPath ))
  216. {
  217. Log( "Failed to load config\n" );
  218. return 1;
  219. }
  220. Log( "Loading ziplist.\n" );
  221. if (Config.UseZipSupport == true && Profile.Minizip.LoadUnzipList( ZipListPath ))
  222. {
  223. Log( "Failed to load ziplist\n" );
  224. return 1;
  225. }
  226. // Initialize defaults, Video and Audio subsystems
  227. Log( "Initializing SDL.\n" );
  228. if (SDL_Init( SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER|SDL_INIT_JOYSTICK )==-1)
  229. {
  230. Log( "Failed to initialize SDL: %s.\n", SDL_GetError() );
  231. return 1;
  232. }
  233. Log( "SDL initialized.\n" );
  234. // Setup SDL Screen
  235. flags = SCREEN_FLAGS;
  236. if (Config.Fullscreen == true)
  237. {
  238. flags |= SDL_FULLSCREEN;
  239. }
  240. Screen = SDL_SetVideoMode( Config.ScreenWidth, Config.ScreenHeight, Config.ScreenDepth, flags );
  241. if (Screen == NULL)
  242. {
  243. Log( "Failed to %dx%dx%d video mode: %s\n", Config.ScreenWidth, Config.ScreenHeight, Config.ScreenDepth, SDL_GetError() );
  244. return 1;
  245. }
  246. // Refresh entire screen for the first frame
  247. UpdateRect( 0, 0, Config.ScreenWidth, Config.ScreenHeight );
  248. // Load joystick
  249. #if !defined(PANDORA) && !defined(X86)
  250. Joystick = SDL_JoystickOpen(0);
  251. if (Joystick == NULL)
  252. {
  253. Log( "Warning failed to open first joystick: %s\n", SDL_GetError() );
  254. }
  255. #endif
  256. // Setup TTF SDL
  257. if (TTF_Init() == -1)
  258. {
  259. Log( "Failed to init TTF_Init: %s\n", TTF_GetError() );
  260. return 1;
  261. }
  262. // Load ttf font
  263. Fonts.at(FONT_SIZE_SMALL) = TTF_OpenFont( Config.PathFont.c_str(), Config.FontSizes.at(FONT_SIZE_SMALL) );
  264. if (!Fonts.at(FONT_SIZE_SMALL))
  265. {
  266. Log( "Failed to open small TTF_OpenFont: %s\n", TTF_GetError() );
  267. return 1;
  268. }
  269. Fonts.at(FONT_SIZE_MEDIUM) = TTF_OpenFont( Config.PathFont.c_str(), Config.FontSizes.at(FONT_SIZE_MEDIUM) );
  270. if (!Fonts.at(FONT_SIZE_MEDIUM))
  271. {
  272. Log( "Failed to open medium TTF_OpenFont: %s\n", TTF_GetError() );
  273. return 1;
  274. }
  275. Fonts.at(FONT_SIZE_LARGE) = TTF_OpenFont( Config.PathFont.c_str(), Config.FontSizes.at(FONT_SIZE_LARGE) );
  276. if (!Fonts.at(FONT_SIZE_LARGE))
  277. {
  278. Log( "Failed to open large TTF_OpenFont: %s\n", TTF_GetError() );
  279. return 1;
  280. }
  281. Log( "Loading profile.\n" );
  282. if (Profile.Load( ProfilePath, Config.Delimiter ))
  283. {
  284. Log( "Failed to load profile\n" );
  285. return 1;
  286. }
  287. // Load images
  288. ImageBackground = LoadImage( Config.PathBackground );
  289. for (button_index=0; button_index<Config.PathButtons.size(); button_index++)
  290. {
  291. ImageButtons.at(button_index) = LoadImage( Config.PathButtons.at(button_index) );
  292. }
  293. // Mouse pointer
  294. if (Config.ShowPointer==true)
  295. {
  296. ImagePointer = LoadImage( Config.PathPointer );
  297. if (ImagePointer == NULL)
  298. {
  299. SDL_ShowCursor( SDL_ENABLE );
  300. }
  301. else
  302. {
  303. SDL_ShowCursor( SDL_DISABLE );
  304. }
  305. }
  306. else
  307. {
  308. SDL_ShowCursor( SDL_DISABLE );
  309. }
  310. // List selector pointer
  311. ImageSelectPointer = LoadImage( Config.PathSelectPointer );
  312. if (ImageSelectPointer == NULL)
  313. {
  314. ImageSelectPointer = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_MEDIUM), ENTRY_ARROW, Config.Colors.at(COLOR_BLACK) );
  315. }
  316. // Title text
  317. text = string(APPNAME) + " " + string(APPVERSION);
  318. if (Profile.TargetApp.length() > 0)
  319. {
  320. text += " for " + Profile.TargetApp;
  321. }
  322. ImageTitle = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_LARGE), text.c_str(), Config.Colors.at(Config.ColorFontFiles) );
  323. if (ImageTitle == NULL)
  324. {
  325. Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() );
  326. return 1;
  327. }
  328. // About text
  329. text = "Written by " + string(APPAUTHOR) + " " + string(APPCOPYRIGHT);
  330. ImageAbout = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_SMALL), text.c_str(), Config.Colors.at(Config.ColorFontFiles) );
  331. if (ImageAbout == NULL)
  332. {
  333. Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() );
  334. return 1;
  335. }
  336. return 0;
  337. }
  338. void CSelector::CloseResources( int8_t result )
  339. {
  340. uint8_t button_index;
  341. if (result == 0)
  342. {
  343. Config.Save( ConfigPath );
  344. Profile.Save( ProfilePath, Config.Delimiter );
  345. }
  346. if (Config.UseZipSupport == true)
  347. {
  348. Profile.Minizip.SaveUnzipList( ZipListPath );
  349. }
  350. // Close joystick
  351. if (Joystick != NULL)
  352. {
  353. Log( "Closing SDL Joystick.\n" );
  354. SDL_JoystickClose( Joystick );
  355. Joystick = NULL;
  356. }
  357. // Close fonts
  358. Log( "Closing TTF fonts.\n" );
  359. if (Fonts.at(FONT_SIZE_SMALL) != NULL)
  360. {
  361. TTF_CloseFont( Fonts.at(FONT_SIZE_SMALL) );
  362. Fonts.at(FONT_SIZE_SMALL) = NULL;
  363. }
  364. if (Fonts.at(FONT_SIZE_MEDIUM) != NULL)
  365. {
  366. TTF_CloseFont( Fonts.at(FONT_SIZE_MEDIUM) );
  367. Fonts.at(FONT_SIZE_MEDIUM) = NULL;
  368. }
  369. if (Fonts.at(FONT_SIZE_LARGE) != NULL)
  370. {
  371. TTF_CloseFont( Fonts.at(FONT_SIZE_LARGE) );
  372. Fonts.at(FONT_SIZE_LARGE) = NULL;
  373. }
  374. // Free images
  375. FREE_IMAGE( ImageBackground );
  376. FREE_IMAGE( ImagePointer );
  377. FREE_IMAGE( ImageSelectPointer );
  378. FREE_IMAGE( ImagePreview );
  379. FREE_IMAGE( ImageTitle );
  380. FREE_IMAGE( ImageAbout );
  381. FREE_IMAGE( ImageFilePath );
  382. FREE_IMAGE( ImageFilter );
  383. FREE_IMAGE( ImageIndex );
  384. FREE_IMAGE( ImageZipMode );
  385. #if defined(DEBUG)
  386. FREE_IMAGE( ImageDebug );
  387. #endif
  388. for (button_index=0; button_index<ImageButtons.size(); button_index++)
  389. {
  390. FREE_IMAGE( ImageButtons.at(button_index) );
  391. }
  392. Log( "Quitting TTF.\n" );
  393. TTF_Quit();
  394. Log( "Quitting SDL.\n" );
  395. SDL_Quit();
  396. // Flush all std buffers before exit
  397. fflush( stdout );
  398. fflush( stderr );
  399. }
  400. int16_t CSelector::DisplayScreen( void )
  401. {
  402. while (IsEventOff(EVENT_QUIT) == true && (IsEventOff(EVENT_SELECT) == true || Mode != MODE_SELECT_ENTRY) )
  403. {
  404. // Get user input
  405. if (PollInputs())
  406. {
  407. return -2;
  408. }
  409. // Select the mode
  410. SelectMode();
  411. // Configure the buttons according to the mode
  412. if (ConfigureButtons())
  413. {
  414. return -2;
  415. }
  416. // Draw the selector
  417. if (DisplaySelector())
  418. {
  419. return -2;
  420. }
  421. // Update the screen
  422. UpdateScreen();
  423. }
  424. if (IsEventOn( EVENT_QUIT ) == true)
  425. {
  426. // Detete any files exracted from zip
  427. Profile.Minizip.DelUnzipFiles();
  428. return -1;
  429. }
  430. else
  431. {
  432. return DisplayList.at(MODE_SELECT_ENTRY).absolute;
  433. }
  434. }
  435. void CSelector::UpdateRect( int16_t x, int16_t y, int16_t w, int16_t h )
  436. {
  437. SDL_Rect rect;
  438. if (Config.ScreenFlip == false)
  439. {
  440. // Safety Checks
  441. if( x < 0 )
  442. {
  443. x = 0;
  444. Log( "ERROR: UpdateRect X was out of bounds\n" );
  445. }
  446. if( y < 0 )
  447. {
  448. y = 0;
  449. Log( "ERROR: UpdateRect Y was out of bounds\n" );
  450. }
  451. if( h < 0 )
  452. {
  453. h = 0;
  454. Log( "ERROR: UpdateRect X was out of bounds\n" );
  455. }
  456. if( w < 0 )
  457. {
  458. w = 0;
  459. Log( "ERROR: UpdateRect Y was out of bounds\n" );
  460. }
  461. if( x > Config.ScreenWidth )
  462. {
  463. x = Config.ScreenWidth-1;
  464. Log( "ERROR: UpdateRect X was out of bounds\n" );
  465. }
  466. if( y > Config.ScreenHeight )
  467. {
  468. y = Config.ScreenHeight-1;
  469. Log( "ERROR: UpdateRect Y was out of bounds\n" );
  470. }
  471. if( x + w > Config.ScreenWidth )
  472. {
  473. w = Config.ScreenWidth-x;
  474. Log( "ERROR: UpdateRect W was out of bounds\n" );
  475. }
  476. if( y + h > Config.ScreenHeight )
  477. {
  478. h = Config.ScreenHeight-y;
  479. Log( "ERROR: UpdateRect H was out of bounds\n" );
  480. }
  481. rect.x = x;
  482. rect.y = y;
  483. rect.w = w;
  484. rect.h = h;
  485. ScreenRectsDirty.push_back( rect );
  486. }
  487. }
  488. void CSelector::UpdateScreen( void )
  489. {
  490. #if defined(DEBUG_FORCE_REDRAW)
  491. Redraw = true;
  492. #endif
  493. if (SkipFrame == false && Redraw == true)
  494. {
  495. if (Config.ScreenFlip == true)
  496. {
  497. if (SDL_Flip( Screen ) != 0)
  498. {
  499. Log( "Failed to swap the buffers: %s\n", SDL_GetError() );
  500. }
  501. }
  502. else
  503. {
  504. SDL_UpdateRects( Screen, ScreenRectsDirty.size(), &ScreenRectsDirty[0] );
  505. }
  506. Redraw = false;
  507. FramesDrawn++;
  508. }
  509. else
  510. {
  511. if (SkipFrame == true)
  512. {
  513. FramesSkipped++;
  514. }
  515. else
  516. {
  517. FramesSleep++;
  518. }
  519. }
  520. ScreenRectsDirty.clear();
  521. FrameEndTime = SDL_GetTicks();
  522. FrameDelay = (MS_PER_SEC/FRAMES_PER_SEC) - (FrameEndTime - FrameStartTime);
  523. #if defined(DEBUG_FPS)
  524. LoopTimeAverage = (LoopTimeAverage + (FrameEndTime - FrameStartTime))/2;
  525. #endif
  526. if (FrameDelay < 0)
  527. {
  528. if (FramesSkipped/FramesDrawn < FRAME_SKIP_RATIO)
  529. {
  530. SkipFrame = true;
  531. }
  532. else // Force a frame to be drawn
  533. {
  534. SkipFrame = false;
  535. }
  536. }
  537. else
  538. {
  539. SkipFrame = false;
  540. SDL_Delay( MIN(FrameDelay, MS_PER_SEC) );
  541. }
  542. FrameStartTime = SDL_GetTicks();
  543. #if defined(DEBUG_FPS)
  544. if (FrameStartTime - FrameCountTime >= MS_PER_SEC)
  545. {
  546. FrameCountTime = FrameStartTime;
  547. FPSDrawn = FramesDrawn;
  548. FPSSkip = FramesSkipped;
  549. FPSSleep = FramesSleep;
  550. FramesDrawn = 1;
  551. FramesSkipped = 0;
  552. FramesSleep = 0;
  553. cout << "DEBUG total " << i_to_a(FPSDrawn+FPSSkip+FPSSleep)
  554. << " fps " << i_to_a(FPSDrawn) << " skip " << i_to_a(FPSSkip) << " slp " << i_to_a(FPSSleep)
  555. << " loop " << i_to_a(LoopTimeAverage) << endl;
  556. }
  557. #endif
  558. }
  559. void CSelector::SelectMode( void )
  560. {
  561. uint8_t old_mode;
  562. old_mode = Mode;
  563. switch (Mode)
  564. {
  565. case MODE_SELECT_ENTRY:
  566. if (IsEventOn( EVENT_CFG_ITEM ) == true)
  567. {
  568. if (ItemsEntry.size()>0)
  569. {
  570. if (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Type == TYPE_FILE )
  571. // || (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Type == TYPE_DIR && Profile.LaunchableDirs == true))
  572. {
  573. // Profile.ScanRomPlugins(Profile.FilePath+ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Name, ItemsRomOption);
  574. // Per Rom Plugin selection. Find ROMCRC and Load Plugins for this rom
  575. Mode = MODE_ROM_OPTION;
  576. }
  577. }
  578. }
  579. else if (IsEventOn( EVENT_CFG_APP ) == true)
  580. {
  581. Mode = MODE_SELECT_OPTION;
  582. }
  583. break;
  584. case MODE_SELECT_ARGUMENT:
  585. if (IsEventOn( EVENT_BACK ) == true)
  586. {
  587. Mode = MODE_SELECT_ENTRY;
  588. }
  589. if (IsEventOn( EVENT_SELECT ) == true)
  590. {
  591. Mode = MODE_SELECT_VALUE;
  592. }
  593. break;
  594. case MODE_SELECT_VALUE:
  595. if (IsEventOn( EVENT_BACK ) == true)
  596. {
  597. Mode = MODE_SELECT_ARGUMENT;
  598. }
  599. break;
  600. case MODE_SELECT_OPTION:
  601. if (IsEventOn( EVENT_BACK ) == true)
  602. {
  603. Mode = MODE_SELECT_ENTRY;
  604. }
  605. if (IsEventOn( EVENT_SELECT ) == true)
  606. {
  607. WhichPlugin = DisplayList.at(MODE_SELECT_OPTION).absolute;
  608. Mode = MODE_SELECT_PLUGIN;
  609. }
  610. break;
  611. case MODE_ROM_OPTION:
  612. if (IsEventOn( EVENT_BACK ) == true)
  613. {
  614. Mode = MODE_SELECT_ENTRY;
  615. }
  616. if (IsEventOn( EVENT_SELECT ) == true)
  617. {
  618. WhichPlugin = DisplayList.at(MODE_ROM_OPTION).absolute;
  619. Mode = MODE_ROM_PLUGIN;
  620. }
  621. break;
  622. case MODE_SELECT_PLUGIN:
  623. if (IsEventOn( EVENT_BACK ) == true)
  624. {
  625. Mode = MODE_SELECT_OPTION;
  626. }
  627. if (IsEventOn( EVENT_SELECT ) == true)
  628. {
  629. Profile.SaveDef1Plugin(WhichPlugin, DisplayList.at(MODE_SELECT_PLUGIN).absolute);
  630. Mode = MODE_SELECT_OPTION;
  631. }
  632. break;
  633. case MODE_ROM_PLUGIN:
  634. if (IsEventOn( EVENT_BACK ) == true)
  635. {
  636. Mode = MODE_ROM_OPTION;
  637. }
  638. if (IsEventOn( EVENT_SELECT ) == true)
  639. {
  640. Profile.SaveRom1Plugin(WhichPlugin, ItemsRomPlugin[DisplayList.at(MODE_ROM_PLUGIN).absolute].Entry);
  641. Mode = MODE_ROM_OPTION;
  642. }
  643. break;
  644. default:
  645. Mode = MODE_SELECT_ENTRY;
  646. Log( "Error: Unknown Mode\n" );
  647. break;
  648. }
  649. if (Mode != old_mode)
  650. {
  651. DrawState_ButtonL = true;
  652. DrawState_ButtonR = true;
  653. Rescan = true;
  654. }
  655. }
  656. int8_t CSelector::DisplaySelector( void )
  657. {
  658. SDL_Rect rect_pos = { Config.EntryXOffset, Config.EntryYOffset, 0 ,0 };
  659. if (Rescan)
  660. {
  661. RescanItems();
  662. RefreshList = true;
  663. Rescan = false;
  664. }
  665. if (RefreshList)
  666. {
  667. PopulateList();
  668. DrawState_Index = true;
  669. Redraw = true;
  670. RefreshList = false;
  671. }
  672. if (Redraw == true || CurScrollPause != 0 || CurScrollSpeed != 0 || TextScrollOffset != 0)
  673. {
  674. if (Config.ScreenFlip == true)
  675. {
  676. DrawState_Title = true;
  677. DrawState_About = true;
  678. DrawState_Filter = true;
  679. DrawState_FilePath = true;
  680. DrawState_Index = true;
  681. DrawState_ZipMode = true;
  682. DrawState_Preview = true;
  683. DrawState_ButtonL = true;
  684. DrawState_ButtonR = true;
  685. }
  686. #if defined(DEBUG_DRAW_STATES)
  687. else
  688. {
  689. cout << "DEBUG "
  690. << " " << i_to_a(DrawState_Title)
  691. << " " << i_to_a(DrawState_About)
  692. << " " << i_to_a(DrawState_Filter)
  693. << " " << i_to_a(DrawState_FilePath)
  694. << " " << i_to_a(DrawState_Index)
  695. << " " << i_to_a(DrawState_ZipMode)
  696. << " " << i_to_a(DrawState_Preview)
  697. << " " << i_to_a(DrawState_ButtonL)
  698. << " " << i_to_a(DrawState_ButtonR) << endl;
  699. }
  700. #endif
  701. // Draw background or clear screen
  702. DrawBackground();
  703. // Draw text titles to the screen
  704. if (DrawText( rect_pos ))
  705. {
  706. return 1;
  707. }
  708. // Draw the buttons for touchscreen
  709. if (DrawButtons( rect_pos ))
  710. {
  711. return 1;
  712. }
  713. // Draw the names for the items for display
  714. if (DrawNames( rect_pos ))
  715. {
  716. return 1;
  717. }
  718. // Custom mouse pointer
  719. if (Config.ShowPointer == true && ImagePointer != NULL)
  720. {
  721. ApplyImage( Mouse.x, Mouse.y, ImagePointer, Screen, NULL );
  722. }
  723. }
  724. return 0;
  725. }
  726. void CSelector::DirectoryUp( void )
  727. {
  728. if (Profile.FilePath.length() > 0)
  729. {
  730. if (Profile.FilePath.at( Profile.FilePath.length()-1) == '/')
  731. {
  732. Profile.FilePath.erase( Profile.FilePath.length()-1 );
  733. }
  734. Profile.FilePath = Profile.FilePath.substr( 0, Profile.FilePath.find_last_of('/', Profile.FilePath.length()-1) ) + '/';
  735. DrawState_FilePath = true;
  736. Rescan = true;
  737. }
  738. else
  739. {
  740. Log( "Error: Filepath is empty\n" );
  741. }
  742. }
  743. void CSelector::DirectoryDown( void )
  744. {
  745. if (DisplayList.at(MODE_SELECT_ENTRY).absolute < (int16_t)ItemsEntry.size() )
  746. {
  747. if (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Type == TYPE_DIR )
  748. {
  749. Profile.FilePath += ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Name + '/';
  750. DrawState_FilePath = true;
  751. Rescan = true;
  752. EventPressCount.at(EVENT_SELECT) = EVENT_LOOPS_OFF;
  753. }
  754. }
  755. else
  756. {
  757. Log( "Error: Item index of %d too large for size of scanitems %d\n", DisplayList.at(MODE_SELECT_ENTRY).absolute, ItemsEntry.size() );
  758. }
  759. }
  760. void CSelector::ZipUp( void )
  761. {
  762. DrawState_FilePath = true;
  763. DrawState_ZipMode = true;
  764. DrawState_ButtonL = true;
  765. Rescan = true;
  766. Profile.ZipFile = "";
  767. }
  768. void CSelector::ZipDown( void )
  769. {
  770. DrawState_FilePath = true;
  771. DrawState_ZipMode = true;
  772. DrawState_ButtonL = true;
  773. Rescan = true;
  774. Profile.ZipFile = ItemsEntry.at(DisplayList.at(Mode).absolute).Name;
  775. EventPressCount.at( EVENT_SELECT ) = EVENT_LOOPS_OFF;
  776. }
  777. void CSelector::RescanItems( void )
  778. {
  779. uint16_t total;
  780. switch (Mode)
  781. {
  782. case MODE_SELECT_ENTRY:
  783. Profile.ScanDir( Profile.FilePath, Config.ShowHidden, Config.UseZipSupport, ItemsEntry );
  784. total = ItemsEntry.size();
  785. break;
  786. case MODE_SELECT_ARGUMENT:
  787. Profile.ScanEntry( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument );
  788. total = ItemsArgument.size();
  789. break;
  790. case MODE_SELECT_VALUE:
  791. Profile.ScanArgument( ItemsArgument.at(DisplayList.at(MODE_SELECT_ARGUMENT).absolute), ItemsValue );
  792. total = ItemsValue.size();
  793. break;
  794. case MODE_SELECT_OPTION:
  795. //Profile.ScanOptions( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument );
  796. Profile.ScanDefPlugins( ItemsArgument );
  797. total = ItemsArgument.size();
  798. break;
  799. case MODE_ROM_OPTION:
  800. //Profile.ScanOptions( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument );
  801. Profile.ScanRomPlugins(Profile.FilePath+ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Name, ItemsRomOption);
  802. total = ItemsRomOption.size();
  803. break;
  804. case MODE_SELECT_PLUGIN:
  805. //Profile.ScanOptions( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument );
  806. Profile.ScanDef1Plugins( WhichPlugin, ItemsDefPlugin );
  807. total = ItemsDefPlugin.size();
  808. break;
  809. case MODE_ROM_PLUGIN:
  810. //Profile.ScanOptions( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument );
  811. Profile.ScanRom1Plugins( WhichPlugin, ItemsRomPlugin );
  812. total = ItemsRomPlugin.size();
  813. break;
  814. default:
  815. total = 0;
  816. Log( "Error: Unknown Mode\n" );
  817. break;
  818. }
  819. if (total > Config.MaxEntries)
  820. {
  821. RectEntries.resize( Config.MaxEntries );
  822. }
  823. else
  824. {
  825. RectEntries.resize( total );
  826. }
  827. ListNames.resize( RectEntries.size() );
  828. DisplayList.at(Mode).absolute = 0;
  829. DisplayList.at(Mode).relative = 0;
  830. DisplayList.at(Mode).first = 0;
  831. DisplayList.at(Mode).last = 0;
  832. DisplayList.at(Mode).total = total;
  833. }
  834. void CSelector::PopulateList( void )
  835. {
  836. // Set limits
  837. SelectionLimits( DisplayList.at( Mode ) );
  838. switch (Mode)
  839. {
  840. case MODE_SELECT_ENTRY:
  841. PopModeEntry();
  842. break;
  843. case MODE_SELECT_ARGUMENT:
  844. PopModeArgument();
  845. break;
  846. case MODE_SELECT_VALUE:
  847. PopModeValue();
  848. break;
  849. case MODE_SELECT_OPTION:
  850. PopModeOption();
  851. break;
  852. case MODE_ROM_OPTION:
  853. PopModeRomOption();
  854. break;
  855. case MODE_SELECT_PLUGIN:
  856. PopModePlugin();
  857. break;
  858. case MODE_ROM_PLUGIN:
  859. PopModeRomPlugin();
  860. break;
  861. default:
  862. Log( "Error: CSelector::PopulateList Unknown Mode\n" );
  863. break;
  864. }
  865. }
  866. void CSelector::PopModeEntry( void )
  867. {
  868. uint16_t i;
  869. uint16_t index;
  870. for (i=0; i<ListNames.size(); i++)
  871. {
  872. index = DisplayList.at( MODE_SELECT_ENTRY ).first+i;
  873. if (CheckRange( index, ItemsEntry.size() ))
  874. {
  875. ListNames.at(i).text.clear();
  876. if (ItemsEntry.at(index).Entry >= 0)
  877. {
  878. ListNames.at(i).text = Profile.Entries.at(ItemsEntry.at(index).Entry).Alias;
  879. }
  880. if (ListNames.at(i).text.length() == 0)
  881. {
  882. ListNames.at(i).text = ItemsEntry.at(index).Name;
  883. }
  884. if (Config.ShowExts == false)
  885. {
  886. ListNames.at(i).text = ListNames.at(i).text.substr( 0, ListNames.at(i).text.find_last_of(".") );
  887. }
  888. ListNames.at(i).text = ListNames.at(i).text;
  889. if (index == DisplayList.at(Mode).absolute)
  890. {
  891. ListNames.at(i).font = FONT_SIZE_LARGE;
  892. LoadPreview( ListNames.at(i).text ); // Load preview
  893. }
  894. else
  895. {
  896. ListNames.at(i).font = FONT_SIZE_MEDIUM;
  897. }
  898. ListNames.at(i).color = Config.ColorFontFiles;
  899. if (ItemsEntry.at(index).Type == TYPE_DIR)
  900. {
  901. ListNames.at(i).color = Config.ColorFontFolders;
  902. }
  903. }
  904. else
  905. {
  906. Log( "Error: CSelector::PopulateModeSelectEntry Index Error\n" );
  907. }
  908. }
  909. }
  910. void CSelector::PopModeArgument( void )
  911. {
  912. uint16_t i;
  913. uint16_t index;
  914. for (i=0; i<ListNames.size(); i++)
  915. {
  916. index = DisplayList.at(MODE_SELECT_ARGUMENT).first+i;
  917. if (CheckRange( index, ItemsArgument.size() ))
  918. {
  919. ListNames.at(i).text = ItemsArgument.at(index).Name;
  920. if (i == DisplayList.at(MODE_SELECT_ARGUMENT).absolute)
  921. {
  922. ListNames.at(i).font = FONT_SIZE_LARGE;
  923. }
  924. else
  925. {
  926. ListNames.at(i).font = FONT_SIZE_MEDIUM;
  927. }
  928. ListNames.at(i).color = Config.ColorFontFiles;
  929. }
  930. else
  931. {
  932. Log( "Error: PopModeArgument index is out of range\n" );
  933. }
  934. }
  935. }
  936. void CSelector::PopModeValue( void )
  937. {
  938. uint16_t i;
  939. uint16_t index;
  940. int16_t defvalue;
  941. int16_t entry;
  942. listoption_t argument;
  943. if (CheckRange(DisplayList.at(MODE_SELECT_ARGUMENT).absolute, ItemsArgument.size() ))
  944. {
  945. argument = ItemsArgument.at(DisplayList.at(MODE_SELECT_ARGUMENT).absolute);
  946. for (i=0; i<ListNames.size(); i++)
  947. {
  948. index = DisplayList.at(MODE_SELECT_VALUE).first+i;
  949. if (CheckRange( index, ItemsValue.size() ))
  950. {
  951. ListNames.at(i).text = ItemsValue.at(index);
  952. if (index == DisplayList.at(MODE_SELECT_VALUE).absolute)
  953. {
  954. ListNames.at(i).font = FONT_SIZE_LARGE;
  955. }
  956. else
  957. {
  958. ListNames.at(i).font = FONT_SIZE_MEDIUM;
  959. }
  960. // Detect the default value
  961. if (ItemsArgument.at(DisplayList.at(MODE_SELECT_ARGUMENT).absolute).Command >= 0)
  962. {
  963. if (SetAllEntryValue == true)
  964. {
  965. Profile.Commands.at(argument.Command).Arguments.at(argument.Argument).Default = DisplayList.at(MODE_SELECT_VALUE).absolute;
  966. }
  967. defvalue = Profile.Commands.at(argument.Command).Arguments.at(argument.Argument).Default;
  968. }
  969. else
  970. {
  971. if (SetAllEntryValue == true)
  972. {
  973. Profile.Extensions.at(argument.Extension).Arguments.at(argument.Argument).Default = DisplayList.at(MODE_SELECT_VALUE).absolute;
  974. }
  975. defvalue = Profile.Extensions.at(argument.Extension).Arguments.at(argument.Argument).Default;
  976. }
  977. if (index==defvalue)
  978. {
  979. ListNames.at(i).text += '*';
  980. }
  981. // Set the color for the selected item for the entry
  982. ListNames.at(i).color = Config.ColorFontFiles;
  983. if (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry<0)
  984. {
  985. // A custom value has been selected, so create a new entry
  986. if (SetOneEntryValue == true)
  987. {
  988. entry = Profile.AddEntry( argument, ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Name );
  989. if (entry>0)
  990. {
  991. ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry = entry;
  992. }
  993. else
  994. {
  995. Log( "Error: Could not create new entry\n" );
  996. }
  997. }
  998. else if (index==defvalue)
  999. {
  1000. ListNames.at(i).color = COLOR_RED;
  1001. }
  1002. }
  1003. if (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry>=0)
  1004. {
  1005. if (ItemsArgument.at(DisplayList.at(MODE_SELECT_ARGUMENT).absolute).Command >= 0)
  1006. {
  1007. if (SetOneEntryValue == true || SetAllEntryValue == true)
  1008. {
  1009. Profile.Entries.at(ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry).CmdValues.at(argument.Command+argument.Argument) = DisplayList.at(MODE_SELECT_VALUE).absolute;
  1010. }
  1011. if (index == Profile.Entries.at(ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry).CmdValues.at(argument.Command+argument.Argument))
  1012. {
  1013. ListNames.at(i).color = COLOR_RED;
  1014. }
  1015. }
  1016. else
  1017. {
  1018. if (SetOneEntryValue == true || SetAllEntryValue == true)
  1019. {
  1020. Profile.Entries.at(ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry).ArgValues.at(argument.Argument) = DisplayList.at(MODE_SELECT_VALUE).absolute;
  1021. }
  1022. if (index == Profile.Entries.at(ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry).ArgValues.at(argument.Argument))
  1023. {
  1024. ListNames.at(i).color = COLOR_RED;
  1025. }
  1026. }
  1027. }
  1028. }
  1029. else
  1030. {
  1031. Log( "Error: PopModeValue index is out of range\n" );
  1032. }
  1033. }
  1034. }
  1035. else
  1036. {
  1037. Log( "Error: PopModeValue argument index out of range\n" );
  1038. }
  1039. }
  1040. void CSelector::PopModeOption( void )
  1041. {
  1042. uint16_t i;
  1043. uint16_t index;
  1044. for (i=0; i<ListNames.size(); i++)
  1045. {
  1046. index = DisplayList.at(MODE_SELECT_OPTION).first+i;
  1047. if (CheckRange( index, ItemsArgument.size() ))
  1048. {
  1049. ListNames.at(i).text = ItemsArgument.at(index).Name;
  1050. if (i == DisplayList.at(MODE_SELECT_OPTION).absolute)
  1051. {
  1052. ListNames.at(i).font = FONT_SIZE_LARGE;
  1053. }
  1054. else
  1055. {
  1056. ListNames.at(i).font = FONT_SIZE_MEDIUM;
  1057. }
  1058. ListNames.at(i).color = Config.ColorFontFiles;
  1059. }
  1060. else
  1061. {
  1062. Log( "Error: PopModeOption index is out of range\n" );
  1063. }
  1064. }
  1065. }
  1066. void CSelector::PopModePlugin( void )
  1067. {
  1068. uint16_t i;
  1069. uint16_t index;
  1070. for (i=0; i<ListNames.size(); i++)
  1071. {
  1072. index = DisplayList.at(MODE_SELECT_PLUGIN).first+i;
  1073. if (CheckRange( index, ItemsDefPlugin.size() ))
  1074. {
  1075. ListNames.at(i).text = ItemsDefPlugin.at(index).Name;
  1076. if (i == DisplayList.at(MODE_SELECT_PLUGIN).absolute)
  1077. {
  1078. ListNames.at(i).font = FONT_SIZE_LARGE;
  1079. }
  1080. else
  1081. {
  1082. ListNames.at(i).font = FONT_SIZE_MEDIUM;
  1083. }
  1084. if (ItemsDefPlugin.at(index).Type == TYPE_DIR)
  1085. ListNames.at(i).color = COLOR_RED;
  1086. else
  1087. ListNames.at(i).color = Config.ColorFontFiles;
  1088. }
  1089. else
  1090. {
  1091. Log( "Error: PopModePlugin index is out of range\n" );
  1092. }
  1093. }
  1094. }
  1095. void CSelector::PopModeRomOption( void )
  1096. {
  1097. uint16_t i;
  1098. uint16_t index;
  1099. for (i=0; i<ListNames.size(); i++)
  1100. {
  1101. index = DisplayList.at(MODE_ROM_OPTION).first+i;
  1102. if (CheckRange( index, ItemsRomOption.size() ))
  1103. {
  1104. ListNames.at(i).text = ItemsRomOption.at(index).Name;
  1105. if (i == DisplayList.at(MODE_ROM_OPTION).absolute)
  1106. {
  1107. ListNames.at(i).font = FONT_SIZE_LARGE;
  1108. }
  1109. else
  1110. {
  1111. ListNames.at(i).font = FONT_SIZE_MEDIUM;
  1112. }
  1113. ListNames.at(i).color = Config.ColorFontFiles;
  1114. }
  1115. else
  1116. {
  1117. Log( "Error: PopModeOption index is out of range\n" );
  1118. }
  1119. }
  1120. }
  1121. void CSelector::PopModeRomPlugin( void )
  1122. {
  1123. uint16_t i;
  1124. uint16_t index;
  1125. for (i=0; i<ListNames.size(); i++)
  1126. {
  1127. index = DisplayList.at(MODE_ROM_PLUGIN).first+i;
  1128. if (CheckRange( index, ItemsRomPlugin.size() ))
  1129. {
  1130. ListNames.at(i).text = ItemsRomPlugin.at(index).Name;
  1131. if (i == DisplayList.at(MODE_ROM_PLUGIN).absolute)
  1132. {
  1133. ListNames.at(i).font = FONT_SIZE_LARGE;
  1134. }
  1135. else
  1136. {
  1137. ListNames.at(i).font = FONT_SIZE_MEDIUM;
  1138. }
  1139. if (ItemsRomPlugin.at(index).Type == TYPE_DIR)
  1140. ListNames.at(i).color = COLOR_RED;
  1141. else
  1142. ListNames.at(i).color = Config.ColorFontFiles;
  1143. }
  1144. else
  1145. {
  1146. Log( "Error: PopModePlugin index is out of range\n" );
  1147. }
  1148. }
  1149. }
  1150. void CSelector::LoadPreview( const string& name )
  1151. {
  1152. string filename;
  1153. SDL_Surface* preview = NULL;
  1154. if (ImagePreview != NULL)
  1155. {
  1156. DrawState_Preview = true;
  1157. }
  1158. FREE_IMAGE( ImagePreview );
  1159. filename = Config.PreviewsPath + "/" + name.substr( 0, name.find_last_of(".")) + ".png";
  1160. preview = LoadImage( filename.c_str() );
  1161. if (preview != NULL)
  1162. {
  1163. ImagePreview = ScaleSurface( preview, Config.PreviewWidth, Config.PreviewHeight );
  1164. FREE_IMAGE( preview );
  1165. DrawState_Preview = true;
  1166. }
  1167. }
  1168. int8_t CSelector::DrawNames( SDL_Rect& location )
  1169. {
  1170. uint16_t entry_index;
  1171. uint16_t startx, starty;
  1172. int16_t offset;
  1173. SDL_Rect rect_clip;
  1174. SDL_Surface* text_surface = NULL;
  1175. if (Config.AutoLayout == false)
  1176. {
  1177. location.x = Config.PosX_ListNames;
  1178. location.y = Config.PosY_ListNames;
  1179. }
  1180. startx = location.x;
  1181. starty = location.y;
  1182. if (ListNames.size() <= 0)
  1183. {
  1184. // Empty directories or zip files
  1185. if (Config.UseZipSupport == true && Profile.ZipFile.length() > 0)
  1186. {
  1187. text_surface = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_MEDIUM), EMPTY_ZIP_LABEL, Config.Colors.at(COLOR_BLACK) );
  1188. }
  1189. else
  1190. {
  1191. text_surface = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_MEDIUM), EMPTY_DIR_LABEL, Config.Colors.at(COLOR_BLACK) );
  1192. }
  1193. if (text_surface != NULL)
  1194. {
  1195. location.x += ImageSelectPointer->w;
  1196. rect_clip.x = 0;
  1197. rect_clip.y = 0;
  1198. rect_clip.w = Config.DisplayListMaxWidth-location.x;
  1199. rect_clip.h = text_surface->h;
  1200. ApplyImage( location.x, location.y, text_surface, Screen, &rect_clip );
  1201. ListNameHeight = MAX(ListNameHeight, location.y+text_surface->h );
  1202. location.x -= ImageSelectPointer->w;
  1203. location.y += text_surface->h + Config.EntryYDelta;
  1204. FREE_IMAGE( text_surface );
  1205. }
  1206. else
  1207. {
  1208. Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() );
  1209. return 1;
  1210. }
  1211. }
  1212. else
  1213. {
  1214. for (entry_index=0; entry_index<ListNames.size(); entry_index++)
  1215. {
  1216. offset = 0;
  1217. // Draw the selector pointer
  1218. if (entry_index == DisplayList.at(Mode).relative)
  1219. {
  1220. ApplyImage( location.x, location.y, ImageSelectPointer, Screen, NULL );
  1221. // Reset scroll settings
  1222. if (entry_index != LastSelectedEntry)
  1223. {
  1224. CurScrollPause = 0;
  1225. CurScrollSpeed = 0;
  1226. TextScrollOffset = 0;
  1227. TextScrollDir = true;
  1228. }
  1229. LastSelectedEntry = entry_index;
  1230. }
  1231. text_surface = TTF_RenderText_Solid( Fonts.at(ListNames.at(entry_index).font), ListNames.at(entry_index).text.c_str(), Config.Colors.at(ListNames.at(entry_index).color) );
  1232. if (text_surface != NULL)
  1233. {
  1234. location.x += ImageSelectPointer->w;
  1235. RectEntries.at(entry_index).x = location.x;
  1236. RectEntries.at(entry_index).y = location.y;
  1237. RectEntries.at(entry_index).w = text_surface->w;
  1238. RectEntries.at(entry_index).h = text_surface->h;
  1239. if (text_surface->w > (Config.DisplayListMaxWidth-location.x) )
  1240. {
  1241. RectEntries.at(entry_index).w = Config.DisplayListMaxWidth-location.x;
  1242. if (Config.TextScrollOption == true && DisplayList.at(Mode).relative == entry_index)
  1243. {
  1244. offset = TextScrollOffset;
  1245. if (CurScrollPause > 1)
  1246. {
  1247. CurScrollPause++;
  1248. if (CurScrollPause >= Config.ScrollPauseSpeed)
  1249. {
  1250. CurScrollPause = 1;
  1251. }
  1252. }
  1253. else
  1254. {
  1255. CurScrollSpeed++;
  1256. if (CurScrollSpeed >= Config.ScrollSpeed)
  1257. {
  1258. CurScrollSpeed = 1;
  1259. if (TextScrollDir == true)
  1260. {
  1261. TextScrollOffset += Config.ScreenRatioW;
  1262. }
  1263. else
  1264. {
  1265. TextScrollOffset -= Config.ScreenRatioW;
  1266. }
  1267. Redraw = true;
  1268. }
  1269. if (RectEntries.at(entry_index).w+TextScrollOffset >= text_surface->w)
  1270. {
  1271. TextScrollDir = false;
  1272. CurScrollPause = 2;
  1273. }
  1274. else if (TextScrollOffset <= 0)
  1275. {
  1276. TextScrollDir = true;
  1277. CurScrollPause = 2;
  1278. }
  1279. }
  1280. }
  1281. }
  1282. rect_clip.w = Config.DisplayListMaxWidth-location.x;
  1283. rect_clip.h = text_surface->h;
  1284. rect_clip.x = offset;
  1285. rect_clip.y = 0;
  1286. ApplyImage( location.x, location.y, text_surface, Screen, &rect_clip );
  1287. ListNameHeight = MAX(ListNameHeight, location.y+text_surface->h );
  1288. location.x -= ImageSelectPointer->w;
  1289. location.y += text_surface->h + Config.EntryYDelta;
  1290. FREE_IMAGE( text_surface );
  1291. }
  1292. else
  1293. {
  1294. Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() );
  1295. return 1;
  1296. }
  1297. }
  1298. }
  1299. UpdateRect( startx, starty, Config.DisplayListMaxWidth-startx, ListNameHeight-starty );
  1300. return 0;
  1301. }
  1302. void CSelector::SelectionLimits( item_pos_t& pos )
  1303. {
  1304. if (pos.absolute <= pos.first)
  1305. {
  1306. pos.relative = 0;
  1307. if (pos.absolute < 0)
  1308. {
  1309. pos.absolute = 0;
  1310. }
  1311. pos.first = pos.absolute;
  1312. if (pos.total < Config.MaxEntries)
  1313. {
  1314. pos.last = (pos.total-1);
  1315. }
  1316. else
  1317. {
  1318. pos.last = pos.absolute+(Config.MaxEntries-1);
  1319. }
  1320. }
  1321. else if (pos.absolute >= pos.last)
  1322. {
  1323. if (pos.absolute > (int16_t)(pos.total-1))
  1324. {
  1325. pos.absolute = (pos.total-1);
  1326. }
  1327. pos.first = pos.absolute-(Config.MaxEntries-1);
  1328. pos.last = pos.absolute;
  1329. if (pos.total < Config.MaxEntries)
  1330. {
  1331. pos.relative = (pos.total-1);
  1332. }
  1333. else
  1334. {
  1335. pos.relative = Config.MaxEntries-1;
  1336. }
  1337. if (pos.first < 0)
  1338. {
  1339. pos.first = 0;
  1340. }
  1341. }
  1342. }
  1343. void CSelector::DrawBackground( void )
  1344. {
  1345. if (ImageBackground != NULL)
  1346. {
  1347. ApplyImage( 0, 0, ImageBackground, Screen, NULL );
  1348. }
  1349. else
  1350. {
  1351. SDL_FillRect( Screen, NULL, rgb_to_int(Config.Colors.at(Config.ColorBackground)) );
  1352. }
  1353. }
  1354. int8_t CSelector::ConfigureButtons( void )
  1355. {
  1356. uint16_t i;
  1357. // Common button mappings
  1358. ButtonModesLeft.at(0) = EVENT_ONE_UP;
  1359. ButtonModesLeft.at(1) = EVENT_PAGE_UP;
  1360. ButtonModesLeft.at(2) = EVENT_PAGE_DOWN;
  1361. ButtonModesLeft.at(3) = EVENT_ONE_DOWN;
  1362. ButtonModesRight.at(0) = EVENT_QUIT;
  1363. // Specific button mappings
  1364. switch (Mode)
  1365. {
  1366. case MODE_SELECT_ENTRY:
  1367. ButtonModesLeft.at(4) = EVENT_DIR_UP;
  1368. ButtonModesLeft.at(5) = EVENT_DIR_DOWN;
  1369. if (Config.UseZipSupport == true && Profile.ZipFile.length() > 0)
  1370. {
  1371. ButtonModesLeft.at(6) = EVENT_ZIP_MODE;
  1372. }
  1373. else
  1374. {
  1375. ButtonModesLeft.at(6) = EVENT_NONE;
  1376. }
  1377. ButtonModesRight.at(1) = EVENT_SELECT;
  1378. ButtonModesRight.at(2) = EVENT_CFG_ITEM;
  1379. ButtonModesRight.at(3) = EVENT_NONE;
  1380. ButtonModesRight.at(3) = EVENT_CFG_APP; // TODO
  1381. break;
  1382. case MODE_SELECT_ARGUMENT:
  1383. ButtonModesLeft.at(4) = EVENT_NONE;
  1384. ButtonModesLeft.at(5) = EVENT_NONE;
  1385. ButtonModesLeft.at(6) = EVENT_NONE;
  1386. ButtonModesRight.at(1) = EVENT_BACK;
  1387. ButtonModesRight.at(2) = EVENT_SELECT;
  1388. ButtonModesRight.at(3) = EVENT_NONE;
  1389. break;
  1390. case MODE_SELECT_VALUE:
  1391. ButtonModesLeft.at(4) = EVENT_NONE;
  1392. ButtonModesLeft.at(5) = EVENT_NONE;
  1393. ButtonModesLeft.at(6) = EVENT_NONE;
  1394. ButtonModesRight.at(1) = EVENT_BACK;
  1395. ButtonModesRight.at(2) = EVENT_SET_ALL;
  1396. ButtonModesRight.at(3) = EVENT_SET_ONE;
  1397. break;
  1398. case MODE_SELECT_OPTION:
  1399. ButtonModesLeft.at(4) = EVENT_NONE;
  1400. ButtonModesLeft.at(5) = EVENT_NONE;
  1401. ButtonModesLeft.at(6) = EVENT_NONE;
  1402. ButtonModesRight.at(1) = EVENT_BACK;
  1403. ButtonModesRight.at(2) = EVENT_SELECT;
  1404. ButtonModesRight.at(3) = EVENT_NONE;
  1405. break;
  1406. case MODE_SELECT_PLUGIN:
  1407. ButtonModesLeft.at(4) = EVENT_NONE;
  1408. ButtonModesLeft.at(5) = EVENT_NONE;
  1409. ButtonModesLeft.at(6) = EVENT_NONE;
  1410. ButtonModesRight.at(1) = EVENT_BACK;
  1411. ButtonModesRight.at(2) = EVENT_SELECT;
  1412. ButtonModesRight.at(3) = EVENT_NONE;
  1413. break;
  1414. case MODE_ROM_OPTION:
  1415. ButtonModesLeft.at(4) = EVENT_NONE;
  1416. ButtonModesLeft.at(5) = EVENT_NONE;
  1417. ButtonModesLeft.at(6) = EVENT_NONE;
  1418. ButtonModesRight.at(1) = EVENT_BACK;
  1419. ButtonModesRight.at(2) = EVENT_SELECT;
  1420. ButtonModesRight.at(3) = EVENT_NONE;
  1421. break;
  1422. case MODE_ROM_PLUGIN:
  1423. ButtonModesLeft.at(4) = EVENT_NONE;
  1424. ButtonModesLeft.at(5) = EVENT_NONE;
  1425. ButtonModesLeft.at(6) = EVENT_NONE;
  1426. ButtonModesRight.at(1) = EVENT_BACK;
  1427. ButtonModesRight.at(2) = EVENT_SELECT;
  1428. ButtonModesRight.at(3) = EVENT_NONE;
  1429. break;
  1430. default:
  1431. Log( "Error: Unknown Mode\n" );
  1432. return 1;
  1433. break;
  1434. }
  1435. // Overides for button driven by config options
  1436. for (i=0; i<ButtonModesLeft.size(); i++ )
  1437. {
  1438. if (Config.ButtonModesLeftEnable.at(i) == false)
  1439. {
  1440. ButtonModesLeft.at(i) = EVENT_NONE;
  1441. }
  1442. }
  1443. for (i=0; i<ButtonModesRight.size(); i++ )
  1444. {
  1445. if (Config.ButtonModesRightEnable.at(i) == false)
  1446. {
  1447. ButtonModesRight.at(i) = EVENT_NONE;
  1448. }
  1449. }
  1450. return 0;
  1451. }
  1452. int8_t CSelector::DrawButtons( SDL_Rect& location )
  1453. {
  1454. uint8_t button;
  1455. SDL_Rect preview;
  1456. if (Config.AutoLayout == false)
  1457. {
  1458. location.x = Config.PosX_ButtonLeft;
  1459. location.y = Config.PosY_ButtonLeft;
  1460. }
  1461. // Draw buttons on left
  1462. if (DrawState_ButtonL == true)
  1463. {
  1464. for (button=0; button<BUTTONS_MAX_LEFT; button++)
  1465. {
  1466. RectButtonsLeft.at(button).x = location.x;
  1467. RectButtonsLeft.at(button).y = location.y+(Config.ButtonHeightLeft*button)+(Config.EntryYOffset*button);
  1468. RectButtonsLeft.at(button).w = Config.ButtonWidthLeft;
  1469. RectButtonsLeft.at(button).h = Config.ButtonHeightLeft;
  1470. if (ButtonModesLeft.at(button) != EVENT_NONE)
  1471. {
  1472. if (DrawButton( ButtonModesLeft.at(button), Fonts.at(FONT_SIZE_LARGE), RectButtonsLeft.at(button) ))
  1473. {
  1474. return 1;
  1475. }
  1476. }
  1477. UpdateRect( RectButtonsLeft.at(button).x, RectButtonsLeft.at(button).y, RectButtonsLeft.at(button).w, RectButtonsLeft.at(button).h );
  1478. }
  1479. DrawState_ButtonL = false;
  1480. }
  1481. location.x += Config.ButtonWidthLeft + Config.EntryXOffset;
  1482. // Draw buttons on right
  1483. if (DrawState_ButtonR ==

Large files files are truncated, but you can click here to view the full file