Guest User

Untitled

a guest
May 2nd, 2014
200
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //EmulationStation, a graphical front-end for ROM browsing. Created by Alec "Aloshi" Lofquist.
  2. //http://www.aloshi.com
  3.  
  4. #include <SDL.h>
  5. #include <iostream>
  6. #include <iomanip>
  7. #include "Renderer.h"
  8. #include "components/GuiGameList.h"
  9. #include "SystemData.h"
  10. #include <boost/filesystem.hpp>
  11. #include "components/GuiDetectDevice.h"
  12. #include "AudioManager.h"
  13. #include "platform.h"
  14. #include "Log.h"
  15. #include "Window.h"
  16. #include "EmulationStation.h"
  17. #include "Settings.h"
  18.  
  19. #ifdef _RPI_
  20.     #include <bcm_host.h>
  21. #endif
  22.  
  23. #include <sstream>
  24.  
  25. namespace fs = boost::filesystem;
  26.  
  27. bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height)
  28. {
  29.     if(argc > 1)
  30.     {
  31.         for(int i = 1; i < argc; i++)
  32.         {
  33.             if(strcmp(argv[i], "-w") == 0)
  34.             {
  35.                 *width = atoi(argv[i + 1]);
  36.                 i++; //skip the argument value
  37.             }else if(strcmp(argv[i], "-h") == 0)
  38.             {
  39.                 *height = atoi(argv[i + 1]);
  40.                 i++; //skip the argument value
  41.             }else if(strcmp(argv[i], "--gamelist-only") == 0)
  42.             {
  43.                 Settings::getInstance()->setBool("PARSEGAMELISTONLY", true);
  44.             }else if(strcmp(argv[i], "--ignore-gamelist") == 0)
  45.             {
  46.                 Settings::getInstance()->setBool("IGNOREGAMELIST", true);
  47.             }else if(strcmp(argv[i], "--draw-framerate") == 0)
  48.             {
  49.                 Settings::getInstance()->setBool("DRAWFRAMERATE", true);
  50.             }else if(strcmp(argv[i], "--no-exit") == 0)
  51.             {
  52.                 Settings::getInstance()->setBool("DONTSHOWEXIT", true);
  53.             }else if(strcmp(argv[i], "--debug") == 0)
  54.             {
  55.                 Settings::getInstance()->setBool("DEBUG", true);
  56.                 Log::setReportingLevel(LogDebug);
  57.             }else if(strcmp(argv[i], "--dimtime") == 0)
  58.             {
  59.                 Settings::getInstance()->setInt("DIMTIME", atoi(argv[i + 1]) * 1000);
  60.                 i++; //skip the argument value
  61.             }else if(strcmp(argv[i], "--windowed") == 0)
  62.             {
  63.                 Settings::getInstance()->setBool("WINDOWED", true);
  64.             }else if(strcmp(argv[i], "--help") == 0)
  65.             {
  66.                 std::cout << "EmulationStation, a graphical front-end for ROM browsing.\n";
  67.                 std::cout << "Command line arguments:\n";
  68.                 std::cout << "-w [width in pixels]      set screen width\n";
  69.                 std::cout << "-h [height in pixels]     set screen height\n";
  70.                 std::cout << "--gamelist-only           skip automatic game detection, only read from gamelist.xml\n";
  71.                 std::cout << "--ignore-gamelist     ignore the gamelist (useful for troubleshooting)\n";
  72.                 std::cout << "--draw-framerate      display the framerate\n";
  73.                 std::cout << "--no-exit         don't show the exit option in the menu\n";
  74.                 std::cout << "--debug               even more logging\n";
  75.                 std::cout << "--dimtime [seconds]       time to wait before dimming the screen (default 30, use 0 for never)\n";
  76.  
  77.                 #ifdef USE_OPENGL_DESKTOP
  78.                     std::cout << "--windowed            not fullscreen\n";
  79.                 #endif
  80.  
  81.                 std::cout << "--help                summon a sentient, angry tuba\n\n";
  82.                 std::cout << "More information available in README.md.\n";
  83.                 return false; //exit after printing help
  84.             }
  85.         }
  86.     }
  87.  
  88.     return true;
  89. }
  90.  
  91. bool verifyHomeFolderExists()
  92. {
  93.     //make sure the config directory exists
  94.     std::string home = getHomePath();
  95.     std::string configDir = home + "/.emulationstation";
  96.     if(!fs::exists(configDir))
  97.     {
  98.         std::cout << "Creating config directory \"" << configDir << "\"\n";
  99.         fs::create_directory(configDir);
  100.         if(!fs::exists(configDir))
  101.         {
  102.             std::cerr << "Config directory could not be created!\n";
  103.             return false;
  104.         }
  105.     }
  106.  
  107.     return true;
  108. }
  109.  
  110. //called on exit, assuming we get far enough to have the log initialized
  111. void onExit()
  112. {
  113.     Log::close();
  114.  
  115.     #ifdef _RPI_
  116.         bcm_host_deinit();
  117.     #endif
  118. }
  119.  
  120. int main(int argc, char* argv[])
  121. {
  122.     unsigned int width = 0;
  123.     unsigned int height = 0;
  124.  
  125.     if(!parseArgs(argc, argv, &width, &height))
  126.         return 0;
  127.  
  128.     //if ~/.emulationstation doesn't exist and cannot be created, bail
  129.     if(!verifyHomeFolderExists())
  130.         return 1;
  131.  
  132.     #ifdef _RPI_
  133.         bcm_host_init();
  134.     #endif
  135.  
  136.     //start the logger
  137.     Log::open();
  138.     LOG(LogInfo) << "EmulationStation - " << PROGRAM_VERSION_STRING;
  139.  
  140.     //always close the log and deinit the BCM library on exit
  141.     atexit(&onExit);
  142.  
  143.     Window window;
  144.     if(!window.init(width, height))
  145.     {
  146.         LOG(LogError) << "Window failed to initialize!";
  147.         return 1;
  148.     }
  149.  
  150.     //dont generate joystick events while we're loading (hopefully fixes "automatically started emulator" bug)
  151.     SDL_JoystickEventState(SDL_DISABLE);
  152.  
  153.     //try loading the system config file
  154.     if(!SystemData::loadConfig(SystemData::getConfigPath(), true))
  155.     {
  156.         LOG(LogError) << "Error parsing system config file!";
  157.         return 1;
  158.     }
  159.  
  160.     //make sure it wasn't empty
  161.     if(SystemData::sSystemVector.size() == 0)
  162.     {
  163.         LOG(LogError) << "No systems found! Does at least one system have a game present? (check that extensions match!)";
  164.         return 1;
  165.     }
  166.  
  167.     //choose which GUI to open depending on if an input configuration already exists
  168.     if(fs::exists(InputManager::getConfigPath()))
  169.     {
  170.         GuiGameList::create(&window);
  171.     }else{
  172.         window.pushGui(new GuiDetectDevice(&window));
  173.     }
  174.  
  175.     //generate joystick events since we're done loading
  176.     SDL_JoystickEventState(SDL_ENABLE);
  177.  
  178.     bool sleeping = false;
  179.     unsigned int timeSinceLastEvent = 0;
  180.     int lastTime = 0;
  181.     bool running = true;
  182.     bool canAutoStart = true;
  183.  
  184.     while(running)
  185.     {
  186.         SDL_Event event;
  187.         while(SDL_PollEvent(&event))
  188.         {
  189.             switch(event.type)
  190.             {
  191.                 case SDL_JOYHATMOTION:
  192.                 case SDL_JOYBUTTONDOWN:
  193.                 case SDL_JOYBUTTONUP:
  194.                 case SDL_KEYDOWN:
  195.                 case SDL_KEYUP:
  196.                 case SDL_JOYAXISMOTION:
  197.                     if(window.getInputManager()->parseEvent(event))
  198.                     {
  199.                         sleeping = false;
  200.                         canAutoStart = false;
  201.                         timeSinceLastEvent = 0;
  202.                     }
  203.                     break;
  204.                 case SDL_USEREVENT:
  205.                     //try to poll input devices, but do not necessarily wake up...
  206.                     window.getInputManager()->parseEvent(event);
  207.                     break;
  208.                 case SDL_QUIT:
  209.                     running = false;
  210.                     break;
  211.             }
  212.         }
  213.  
  214.         if(sleeping)
  215.         {
  216.             lastTime = SDL_GetTicks();
  217.             SDL_Delay(1); //this doesn't need to be accurate
  218.             continue;
  219.         }
  220.  
  221.         if(canAutoStart && timeSinceLastEvent > 5000)
  222.         {
  223.             canAutoStart = false;  // only if you want ES to NOT auto start again after its auto-started emulator closes
  224.             timeSinceLastEvent = 0;
  225.             window.deinit();   // shut down the renderer/SDL
  226.             system("/usr/bin/xbmc-standalone");   // (e.g. system("startx");)
  227.             window.init();   // restart the renderer/SDL
  228.             continue;
  229.         }
  230.  
  231.         int curTime = SDL_GetTicks();
  232.         int deltaTime = curTime - lastTime;
  233.         lastTime = curTime;
  234.  
  235.         //cap deltaTime at 1000
  236.         if(deltaTime > 1000 || deltaTime < 0)
  237.             deltaTime = 1000;
  238.  
  239.         window.update(deltaTime);
  240.         Renderer::swapBuffers(); //swap here so we can read the last screen state during updates (see ImageComponent::copyScreen())
  241.         window.render();
  242.  
  243.         //sleep if we're past our threshold
  244.         //sleeping entails setting a flag to start skipping frames
  245.         //and initially drawing a black semi-transparent rect to dim the screen
  246.         timeSinceLastEvent += deltaTime;
  247.         if(timeSinceLastEvent >= (unsigned int)Settings::getInstance()->getInt("DIMTIME") && Settings::getInstance()->getInt("DIMTIME") != 0)
  248.         {
  249.             sleeping = true;
  250.             timeSinceLastEvent = 0;
  251.             Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x000000A0);
  252.             Renderer::swapBuffers();
  253.         }
  254.  
  255.         Log::flush();
  256.     }
  257.  
  258.     Renderer::deinit();
  259.     SystemData::deleteSystems();
  260.  
  261.     std::cout << "EmulationStation cleanly shutting down...\n";
  262.  
  263.     return 0;
  264. }
RAW Paste Data