FreeShop.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include <sys/stat.h>
  2. #include "FreeShop.hpp"
  3. #include "States/TitleState.hpp"
  4. #include "Notification.hpp"
  5. #include "States/DialogState.hpp"
  6. #include "States/LoadingState.hpp"
  7. #include "States/SyncState.hpp"
  8. #include "States/BrowseState.hpp"
  9. #include "States/NewsState.hpp"
  10. #include "Config.hpp"
  11. #include "Util.hpp"
  12. #include "States/SleepState.hpp"
  13. #include "States/QrScannerState.hpp"
  14. using namespace cpp3ds;
  15. using namespace TweenEngine;
  16. namespace FreeShop {
  17. cpp3ds::Uint64 g_requestJump = 0;
  18. bool g_requestShutdown = false;
  19. FreeShop::FreeShop()
  20. : Game(0x100000)
  21. {
  22. m_stateStack = new StateStack(State::Context(m_text, m_data));
  23. m_stateStack->registerState<TitleState>(States::Title);
  24. m_stateStack->registerState<LoadingState>(States::Loading);
  25. m_stateStack->registerState<SyncState>(States::Sync);
  26. m_stateStack->registerState<BrowseState>(States::Browse);
  27. m_stateStack->registerState<SleepState>(States::Sleep);
  28. m_stateStack->registerState<QrScannerState>(States::QrScanner);
  29. m_stateStack->registerState<DialogState>(States::Dialog);
  30. m_stateStack->registerState<NewsState>(States::News);
  31. #ifdef EMULATION
  32. m_stateStack->pushState(States::Browse);
  33. #else
  34. m_stateStack->pushState(States::Loading);
  35. m_stateStack->pushState(States::Sync);
  36. m_stateStack->pushState(States::Title);
  37. #endif
  38. textFPS.setFillColor(cpp3ds::Color::Red);
  39. textFPS.setCharacterSize(20);
  40. // Set up directory structure, if necessary
  41. std::string path = cpp3ds::FileSystem::getFilePath(FREESHOP_DIR);
  42. if (!pathExists(path.c_str(), false))
  43. makeDirectory(path.c_str());
  44. path = cpp3ds::FileSystem::getFilePath(FREESHOP_DIR "/tmp");
  45. if (pathExists(path.c_str(), false))
  46. removeDirectory(path.c_str());
  47. mkdir(path.c_str(), 0777);
  48. path = cpp3ds::FileSystem::getFilePath(FREESHOP_DIR "/cache");
  49. if (!pathExists(path.c_str(), false))
  50. mkdir(path.c_str(), 0777);
  51. path = cpp3ds::FileSystem::getFilePath(FREESHOP_DIR "/keys");
  52. if (!pathExists(path.c_str(), false))
  53. mkdir(path.c_str(), 0777);
  54. Config::loadFromFile();
  55. // If language is not set to auto-detect, load chosen language
  56. std::string langCode = Config::get(Config::Language).GetString();
  57. if (langCode != "auto")
  58. for (int i = 0; i < cpp3ds::Language::COUNT; ++i)
  59. {
  60. // Try to first load by language and not file. This is so
  61. // it can be better known later for fetching game data in proper language
  62. auto language = static_cast<cpp3ds::Language>(i);
  63. if (langCode == cpp3ds::I18n::getInstance().getLangString(language))
  64. {
  65. cpp3ds::I18n::loadLanguage(language);
  66. break;
  67. }
  68. else if (i == cpp3ds::Language::COUNT - 1)
  69. cpp3ds::I18n::loadLanguageFile(_("lang/%s.lang", langCode.c_str()));
  70. }
  71. // If override.lang exists, use it instead of chosen language
  72. std::string testLangFilename(FREESHOP_DIR "/override.lang");
  73. if (pathExists(testLangFilename.c_str()))
  74. cpp3ds::I18n::loadLanguageFile(testLangFilename);
  75. }
  76. FreeShop::~FreeShop()
  77. {
  78. delete m_stateStack;
  79. Config::saveToFile();
  80. #ifdef _3DS
  81. if (g_requestJump != 0)
  82. {
  83. Result res = 0;
  84. u8 hmac[0x20];
  85. memset(hmac, 0, sizeof(hmac));
  86. FS_MediaType mediaType = ((g_requestJump >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD;
  87. if (R_SUCCEEDED(res = APT_PrepareToDoApplicationJump(0, g_requestJump, mediaType)))
  88. res = APT_DoApplicationJump(0, 0, hmac);
  89. }
  90. else if (g_requestShutdown)
  91. {
  92. ptmSysmInit();
  93. PTMSYSM_ShutdownAsync(0);
  94. ptmSysmExit();
  95. }
  96. #endif
  97. }
  98. void FreeShop::update(float delta)
  99. {
  100. // Need to update before checking if empty
  101. m_stateStack->update(delta);
  102. if (m_stateStack->isEmpty() || g_requestJump != 0 || g_requestShutdown)
  103. exit();
  104. Notification::update(delta);
  105. #ifndef NDEBUG
  106. static int i;
  107. if (i++ % 10 == 0) {
  108. textFPS.setString(_("%.1f fps", 1.f / delta));
  109. textFPS.setPosition(395 - textFPS.getGlobalBounds().width, 2.f);
  110. }
  111. #endif
  112. }
  113. void FreeShop::processEvent(Event& event)
  114. {
  115. m_stateStack->processEvent(event);
  116. }
  117. void FreeShop::renderTopScreen(Window& window)
  118. {
  119. window.clear(Color::White);
  120. m_stateStack->renderTopScreen(window);
  121. for (auto& notification : Notification::notifications)
  122. window.draw(*notification);
  123. #ifndef NDEBUG
  124. window.draw(textFPS);
  125. #endif
  126. }
  127. void FreeShop::renderBottomScreen(Window& window)
  128. {
  129. window.clear(Color::White);
  130. m_stateStack->renderBottomScreen(window);
  131. }
  132. } // namespace FreeShop