PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/Core/Core/BootManager.cpp

https://gitlab.com/WoomyNightClub/dolphin
C++ | 398 lines | 311 code | 52 blank | 35 comment | 55 complexity | acc9b7de38b8e7d540dd6dc78f658929 MD5 | raw file
  1. // Copyright 2011 Dolphin Emulator Project
  2. // Licensed under GPLv2+
  3. // Refer to the license.txt file included.
  4. // File description
  5. // -------------
  6. // Purpose of this file: Collect boot settings for Core::Init()
  7. // Call sequence: This file has one of the first function called when a game is booted,
  8. // the boot sequence in the code is:
  9. // DolphinWX: FrameTools.cpp StartGame
  10. // Core BootManager.cpp BootCore
  11. // Core.cpp Init Thread creation
  12. // EmuThread Calls CBoot::BootUp
  13. // Boot.cpp CBoot::BootUp()
  14. // CBoot::EmulatedBS2_Wii() / GC() or Load_BS2()
  15. // Includes
  16. // ----------------
  17. #include <algorithm>
  18. #include <array>
  19. #include <string>
  20. #include <vector>
  21. #include "Common/CommonTypes.h"
  22. #include "Common/FileUtil.h"
  23. #include "Common/IniFile.h"
  24. #include "Common/SysConf.h"
  25. #include "Core/BootManager.h"
  26. #include "Core/ConfigManager.h"
  27. #include "Core/Core.h"
  28. #include "Core/Host.h"
  29. #include "Core/Movie.h"
  30. #include "Core/NetPlayProto.h"
  31. #include "Core/HW/EXI.h"
  32. #include "Core/HW/SI.h"
  33. #include "Core/HW/Sram.h"
  34. #include "Core/HW/WiimoteReal/WiimoteReal.h"
  35. #include "VideoCommon/VideoBackendBase.h"
  36. namespace BootManager
  37. {
  38. // TODO this is an ugly hack which allows us to restore values trampled by per-game settings
  39. // Apply fire liberally
  40. struct ConfigCache
  41. {
  42. public:
  43. // fill the cache with values from the configuration
  44. void SaveConfig(const SConfig& config);
  45. // restore values to the configuration from the cache
  46. void RestoreConfig(SConfig* config);
  47. // These store if the relevant setting should be reset back later (true) or if it should be left alone on restore (false)
  48. bool bSetEmulationSpeed;
  49. bool bSetVolume;
  50. bool bSetFrameSkip;
  51. std::array<bool, MAX_BBMOTES> bSetWiimoteSource;
  52. std::array<bool, MAX_SI_CHANNELS> bSetPads;
  53. std::array<bool, MAX_EXI_CHANNELS> bSetEXIDevice;
  54. private:
  55. bool valid;
  56. bool bCPUThread;
  57. bool bSkipIdle;
  58. bool bSyncGPUOnSkipIdleHack;
  59. bool bFPRF;
  60. bool bAccurateNaNs;
  61. bool bMMU;
  62. bool bDCBZOFF;
  63. bool m_EnableJIT;
  64. bool bSyncGPU;
  65. bool bFastDiscSpeed;
  66. bool bDSPHLE;
  67. bool bHLE_BS2;
  68. bool bProgressive;
  69. bool bPAL60;
  70. int iSelectedLanguage;
  71. int iCPUCore;
  72. int Volume;
  73. unsigned int frameSkip;
  74. float m_EmulationSpeed;
  75. std::string strBackend;
  76. std::string sBackend;
  77. std::string m_strGPUDeterminismMode;
  78. std::array<int, MAX_BBMOTES> iWiimoteSource;
  79. std::array<SIDevices, MAX_SI_CHANNELS> Pads;
  80. std::array<TEXIDevices, MAX_EXI_CHANNELS> m_EXIDevice;
  81. };
  82. void ConfigCache::SaveConfig(const SConfig& config)
  83. {
  84. valid = true;
  85. bCPUThread = config.bCPUThread;
  86. bSkipIdle = config.bSkipIdle;
  87. bSyncGPUOnSkipIdleHack = config.bSyncGPUOnSkipIdleHack;
  88. bFPRF = config.bFPRF;
  89. bAccurateNaNs = config.bAccurateNaNs;
  90. bMMU = config.bMMU;
  91. bDCBZOFF = config.bDCBZOFF;
  92. m_EnableJIT = config.m_DSPEnableJIT;
  93. bSyncGPU = config.bSyncGPU;
  94. bFastDiscSpeed = config.bFastDiscSpeed;
  95. bDSPHLE = config.bDSPHLE;
  96. bHLE_BS2 = config.bHLE_BS2;
  97. bProgressive = config.bProgressive;
  98. bPAL60 = config.bPAL60;
  99. iSelectedLanguage = config.SelectedLanguage;
  100. iCPUCore = config.iCPUCore;
  101. Volume = config.m_Volume;
  102. m_EmulationSpeed = config.m_EmulationSpeed;
  103. frameSkip = config.m_FrameSkip;
  104. strBackend = config.m_strVideoBackend;
  105. sBackend = config.sBackend;
  106. m_strGPUDeterminismMode = config.m_strGPUDeterminismMode;
  107. std::copy(std::begin(g_wiimote_sources), std::end(g_wiimote_sources), std::begin(iWiimoteSource));
  108. std::copy(std::begin(config.m_SIDevice), std::end(config.m_SIDevice), std::begin(Pads));
  109. std::copy(std::begin(config.m_EXIDevice), std::end(config.m_EXIDevice), std::begin(m_EXIDevice));
  110. bSetEmulationSpeed = false;
  111. bSetVolume = false;
  112. bSetFrameSkip = false;
  113. bSetWiimoteSource.fill(false);
  114. bSetPads.fill(false);
  115. bSetEXIDevice.fill(false);
  116. }
  117. void ConfigCache::RestoreConfig(SConfig* config)
  118. {
  119. if (!valid)
  120. return;
  121. valid = false;
  122. config->bCPUThread = bCPUThread;
  123. config->bSkipIdle = bSkipIdle;
  124. config->bSyncGPUOnSkipIdleHack = bSyncGPUOnSkipIdleHack;
  125. config->bFPRF = bFPRF;
  126. config->bAccurateNaNs = bAccurateNaNs;
  127. config->bMMU = bMMU;
  128. config->bDCBZOFF = bDCBZOFF;
  129. config->m_DSPEnableJIT = m_EnableJIT;
  130. config->bSyncGPU = bSyncGPU;
  131. config->bFastDiscSpeed = bFastDiscSpeed;
  132. config->bDSPHLE = bDSPHLE;
  133. config->bHLE_BS2 = bHLE_BS2;
  134. config->bProgressive = bProgressive;
  135. config->bPAL60 = bPAL60;
  136. config->SelectedLanguage = iSelectedLanguage;
  137. config->iCPUCore = iCPUCore;
  138. config->m_SYSCONF->SetData("IPL.PGS", bProgressive);
  139. config->m_SYSCONF->SetData("IPL.E60", bPAL60);
  140. // Only change these back if they were actually set by game ini, since they can be changed while a game is running.
  141. if (bSetVolume)
  142. config->m_Volume = Volume;
  143. if (config->bWii)
  144. {
  145. for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
  146. {
  147. if (bSetWiimoteSource[i])
  148. {
  149. g_wiimote_sources[i] = iWiimoteSource[i];
  150. WiimoteReal::ChangeWiimoteSource(i, iWiimoteSource[i]);
  151. }
  152. }
  153. }
  154. for (unsigned int i = 0; i < MAX_SI_CHANNELS; ++i)
  155. {
  156. if (bSetPads[i])
  157. config->m_SIDevice[i] = Pads[i];
  158. }
  159. if (bSetEmulationSpeed)
  160. config->m_EmulationSpeed = m_EmulationSpeed;
  161. if (bSetFrameSkip)
  162. {
  163. config->m_FrameSkip = frameSkip;
  164. Movie::SetFrameSkipping(frameSkip);
  165. }
  166. for (unsigned int i = 0; i < MAX_EXI_CHANNELS; ++i)
  167. {
  168. if (bSetEXIDevice[i])
  169. config->m_EXIDevice[i] = m_EXIDevice[i];
  170. }
  171. config->m_strVideoBackend = strBackend;
  172. config->sBackend = sBackend;
  173. config->m_strGPUDeterminismMode = m_strGPUDeterminismMode;
  174. VideoBackendBase::ActivateBackend(config->m_strVideoBackend);
  175. }
  176. static ConfigCache config_cache;
  177. static GPUDeterminismMode ParseGPUDeterminismMode(const std::string& mode)
  178. {
  179. if (mode == "auto")
  180. return GPU_DETERMINISM_AUTO;
  181. if (mode == "none")
  182. return GPU_DETERMINISM_NONE;
  183. if (mode == "fake-completion")
  184. return GPU_DETERMINISM_FAKE_COMPLETION;
  185. NOTICE_LOG(BOOT, "Unknown GPU determinism mode %s", mode.c_str());
  186. return GPU_DETERMINISM_AUTO;
  187. }
  188. // Boot the ISO or file
  189. bool BootCore(const std::string& _rFilename)
  190. {
  191. SConfig& StartUp = SConfig::GetInstance();
  192. // Use custom settings for debugging mode
  193. Host_SetStartupDebuggingParameters();
  194. StartUp.m_BootType = SConfig::BOOT_ISO;
  195. StartUp.m_strFilename = _rFilename;
  196. SConfig::GetInstance().m_LastFilename = _rFilename;
  197. SConfig::GetInstance().SaveSettings();
  198. StartUp.bRunCompareClient = false;
  199. StartUp.bRunCompareServer = false;
  200. config_cache.SaveConfig(StartUp);
  201. // If for example the ISO file is bad we return here
  202. if (!StartUp.AutoSetup(SConfig::BOOT_DEFAULT))
  203. return false;
  204. // Load game specific settings
  205. {
  206. IniFile game_ini = StartUp.LoadGameIni();
  207. // General settings
  208. IniFile::Section* core_section = game_ini.GetOrCreateSection("Core");
  209. IniFile::Section* dsp_section = game_ini.GetOrCreateSection("DSP");
  210. IniFile::Section* controls_section = game_ini.GetOrCreateSection("Controls");
  211. core_section->Get("CPUThread", &StartUp.bCPUThread, StartUp.bCPUThread);
  212. core_section->Get("SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle);
  213. core_section->Get("SyncOnSkipIdle", &StartUp.bSyncGPUOnSkipIdleHack, StartUp.bSyncGPUOnSkipIdleHack);
  214. core_section->Get("FPRF", &StartUp.bFPRF, StartUp.bFPRF);
  215. core_section->Get("AccurateNaNs", &StartUp.bAccurateNaNs, StartUp.bAccurateNaNs);
  216. core_section->Get("MMU", &StartUp.bMMU, StartUp.bMMU);
  217. core_section->Get("DCBZ", &StartUp.bDCBZOFF, StartUp.bDCBZOFF);
  218. core_section->Get("SyncGPU", &StartUp.bSyncGPU, StartUp.bSyncGPU);
  219. core_section->Get("FastDiscSpeed", &StartUp.bFastDiscSpeed, StartUp.bFastDiscSpeed);
  220. core_section->Get("DSPHLE", &StartUp.bDSPHLE, StartUp.bDSPHLE);
  221. core_section->Get("GFXBackend", &StartUp.m_strVideoBackend, StartUp.m_strVideoBackend);
  222. core_section->Get("CPUCore", &StartUp.iCPUCore, StartUp.iCPUCore);
  223. core_section->Get("HLE_BS2", &StartUp.bHLE_BS2, StartUp.bHLE_BS2);
  224. core_section->Get("ProgressiveScan", &StartUp.bProgressive, StartUp.bProgressive);
  225. core_section->Get("PAL60", &StartUp.bPAL60, StartUp.bPAL60);
  226. if (core_section->Get("EmulationSpeed", &SConfig::GetInstance().m_EmulationSpeed, SConfig::GetInstance().m_EmulationSpeed))
  227. config_cache.bSetEmulationSpeed = true;
  228. if (core_section->Get("FrameSkip", &SConfig::GetInstance().m_FrameSkip))
  229. {
  230. config_cache.bSetFrameSkip = true;
  231. Movie::SetFrameSkipping(SConfig::GetInstance().m_FrameSkip);
  232. }
  233. if (dsp_section->Get("Volume", &SConfig::GetInstance().m_Volume, SConfig::GetInstance().m_Volume))
  234. config_cache.bSetVolume = true;
  235. dsp_section->Get("EnableJIT", &SConfig::GetInstance().m_DSPEnableJIT, SConfig::GetInstance().m_DSPEnableJIT);
  236. dsp_section->Get("Backend", &SConfig::GetInstance().sBackend, SConfig::GetInstance().sBackend);
  237. VideoBackendBase::ActivateBackend(StartUp.m_strVideoBackend);
  238. core_section->Get("GPUDeterminismMode", &StartUp.m_strGPUDeterminismMode, StartUp.m_strGPUDeterminismMode);
  239. for (unsigned int i = 0; i < MAX_SI_CHANNELS; ++i)
  240. {
  241. int source;
  242. controls_section->Get(StringFromFormat("PadType%u", i), &source, -1);
  243. if (source >= (int) SIDEVICE_NONE && source <= (int) SIDEVICE_WIIU_ADAPTER)
  244. {
  245. SConfig::GetInstance().m_SIDevice[i] = (SIDevices) source;
  246. config_cache.bSetPads[i] = true;
  247. }
  248. }
  249. // Wii settings
  250. if (StartUp.bWii)
  251. {
  252. // Flush possible changes to SYSCONF to file
  253. SConfig::GetInstance().m_SYSCONF->Save();
  254. int source;
  255. for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
  256. {
  257. controls_section->Get(StringFromFormat("WiimoteSource%u", i), &source, -1);
  258. if (source != -1 && g_wiimote_sources[i] != (unsigned) source && source >= WIIMOTE_SRC_NONE && source <= WIIMOTE_SRC_HYBRID)
  259. {
  260. config_cache.bSetWiimoteSource[i] = true;
  261. g_wiimote_sources[i] = source;
  262. WiimoteReal::ChangeWiimoteSource(i, source);
  263. }
  264. }
  265. controls_section->Get("WiimoteSourceBB", &source, -1);
  266. if (source != -1 && g_wiimote_sources[WIIMOTE_BALANCE_BOARD] != (unsigned) source && (source == WIIMOTE_SRC_NONE || source == WIIMOTE_SRC_REAL))
  267. {
  268. config_cache.bSetWiimoteSource[WIIMOTE_BALANCE_BOARD] = true;
  269. g_wiimote_sources[WIIMOTE_BALANCE_BOARD] = source;
  270. WiimoteReal::ChangeWiimoteSource(WIIMOTE_BALANCE_BOARD, source);
  271. }
  272. }
  273. }
  274. StartUp.m_GPUDeterminismMode = ParseGPUDeterminismMode(StartUp.m_strGPUDeterminismMode);
  275. // Movie settings
  276. if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
  277. {
  278. StartUp.bCPUThread = Movie::IsDualCore();
  279. StartUp.bSkipIdle = Movie::IsSkipIdle();
  280. StartUp.bDSPHLE = Movie::IsDSPHLE();
  281. StartUp.bProgressive = Movie::IsProgressive();
  282. StartUp.bPAL60 = Movie::IsPAL60();
  283. StartUp.bFastDiscSpeed = Movie::IsFastDiscSpeed();
  284. StartUp.iCPUCore = Movie::GetCPUMode();
  285. StartUp.bSyncGPU = Movie::IsSyncGPU();
  286. for (int i = 0; i < 2; ++i)
  287. {
  288. if (Movie::IsUsingMemcard(i) && Movie::IsStartingFromClearSave() && !StartUp.bWii)
  289. {
  290. if (File::Exists(File::GetUserPath(D_GCUSER_IDX) + StringFromFormat("Movie%s.raw", (i == 0) ? "A" : "B")))
  291. File::Delete(File::GetUserPath(D_GCUSER_IDX) + StringFromFormat("Movie%s.raw", (i == 0) ? "A" : "B"));
  292. }
  293. }
  294. }
  295. if (NetPlay::IsNetPlayRunning())
  296. {
  297. StartUp.bCPUThread = g_NetPlaySettings.m_CPUthread;
  298. StartUp.bDSPHLE = g_NetPlaySettings.m_DSPHLE;
  299. StartUp.bEnableMemcardSdWriting = g_NetPlaySettings.m_WriteToMemcard;
  300. StartUp.iCPUCore = g_NetPlaySettings.m_CPUcore;
  301. StartUp.SelectedLanguage = g_NetPlaySettings.m_SelectedLanguage;
  302. StartUp.bOverrideGCLanguage = g_NetPlaySettings.m_OverrideGCLanguage;
  303. StartUp.bProgressive = g_NetPlaySettings.m_ProgressiveScan;
  304. StartUp.bPAL60 = g_NetPlaySettings.m_PAL60;
  305. SConfig::GetInstance().m_DSPEnableJIT = g_NetPlaySettings.m_DSPEnableJIT;
  306. SConfig::GetInstance().m_OCEnable = g_NetPlaySettings.m_OCEnable;
  307. SConfig::GetInstance().m_OCFactor = g_NetPlaySettings.m_OCFactor;
  308. SConfig::GetInstance().m_EXIDevice[0] = g_NetPlaySettings.m_EXIDevice[0];
  309. SConfig::GetInstance().m_EXIDevice[1] = g_NetPlaySettings.m_EXIDevice[1];
  310. config_cache.bSetEXIDevice[0] = true;
  311. config_cache.bSetEXIDevice[1] = true;
  312. }
  313. else
  314. {
  315. g_SRAM_netplay_initialized = false;
  316. }
  317. // Apply overrides
  318. // Some NTSC GameCube games such as Baten Kaitos react strangely to language settings that would be invalid on an NTSC system
  319. if (!StartUp.bOverrideGCLanguage && StartUp.bNTSC)
  320. {
  321. StartUp.SelectedLanguage = 0;
  322. }
  323. // Some NTSC Wii games such as Doc Louis's Punch-Out!! and 1942 (Virtual Console) crash if the PAL60 option is enabled
  324. if (StartUp.bWii && StartUp.bNTSC)
  325. {
  326. StartUp.bPAL60 = false;
  327. }
  328. SConfig::GetInstance().m_SYSCONF->SetData("IPL.PGS", StartUp.bProgressive);
  329. SConfig::GetInstance().m_SYSCONF->SetData("IPL.E60", StartUp.bPAL60);
  330. // Run the game
  331. // Init the core
  332. if (!Core::Init())
  333. {
  334. PanicAlertT("Couldn't init the core.\nCheck your configuration.");
  335. return false;
  336. }
  337. return true;
  338. }
  339. void Stop()
  340. {
  341. Core::Stop();
  342. SConfig& StartUp = SConfig::GetInstance();
  343. StartUp.m_strUniqueID = "00000000";
  344. config_cache.RestoreConfig(&StartUp);
  345. }
  346. } // namespace