FreeShop.cpp 4.5 KB

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