FreeShop.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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 "TitleKeys.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. // Load chosen language, correct auto-detect with separate Spanish/Portuguese
  56. std::string langCode = Config::get(Config::Language).GetString();
  57. #ifdef _3DS
  58. u8 region;
  59. CFGU_SecureInfoGetRegion(&region);
  60. if (langCode == "auto")
  61. {
  62. if (cpp3ds::I18n::getLanguage() == cpp3ds::Language::Spanish)
  63. langCode = (region == CFG_REGION_USA) ? "es_US" : "es_ES";
  64. else if (cpp3ds::I18n::getLanguage() == cpp3ds::Language::Portuguese)
  65. langCode = (region == CFG_REGION_USA) ? "pt_BR" : "pt_PT";
  66. }
  67. #endif
  68. if (langCode != "auto")
  69. cpp3ds::I18n::loadLanguageFile(_("lang/%s.lang", langCode.c_str()));
  70. // If override.lang exists, use it instead of chosen language
  71. std::string testLangFilename(FREESHOP_DIR "/override.lang");
  72. if (pathExists(testLangFilename.c_str()))
  73. cpp3ds::I18n::loadLanguageFile(testLangFilename);
  74. }
  75. FreeShop::~FreeShop()
  76. {
  77. delete m_stateStack;
  78. Config::saveToFile();
  79. #ifdef _3DS
  80. if (g_requestJump != 0)
  81. {
  82. Result res = 0;
  83. u8 hmac[0x20];
  84. memset(hmac, 0, sizeof(hmac));
  85. FS_MediaType mediaType = ((g_requestJump >> 32) == TitleKeys::DSiWare) ? MEDIATYPE_NAND : MEDIATYPE_SD;
  86. if (R_SUCCEEDED(res = APT_PrepareToDoApplicationJump(0, g_requestJump, mediaType)))
  87. res = APT_DoApplicationJump(0, 0, hmac);
  88. }
  89. else if (g_requestShutdown)
  90. {
  91. ptmSysmInit();
  92. PTMSYSM_ShutdownAsync(0);
  93. ptmSysmExit();
  94. }
  95. #endif
  96. }
  97. void FreeShop::update(float delta)
  98. {
  99. // Need to update before checking if empty
  100. m_stateStack->update(delta);
  101. if (m_stateStack->isEmpty() || g_requestJump != 0 || g_requestShutdown)
  102. exit();
  103. Notification::update(delta);
  104. #ifndef NDEBUG
  105. static int i;
  106. if (i++ % 10 == 0) {
  107. textFPS.setString(_("%.1f fps", 1.f / delta));
  108. textFPS.setPosition(395 - textFPS.getGlobalBounds().width, 2.f);
  109. }
  110. #endif
  111. }
  112. void FreeShop::processEvent(Event& event)
  113. {
  114. m_stateStack->processEvent(event);
  115. }
  116. void FreeShop::renderTopScreen(Window& window)
  117. {
  118. window.clear(Color::White);
  119. m_stateStack->renderTopScreen(window);
  120. for (auto& notification : Notification::notifications)
  121. window.draw(*notification);
  122. #ifndef NDEBUG
  123. window.draw(textFPS);
  124. #endif
  125. }
  126. void FreeShop::renderBottomScreen(Window& window)
  127. {
  128. window.clear(Color::White);
  129. m_stateStack->renderBottomScreen(window);
  130. }
  131. } // namespace FreeShop