1 // Copyright 2008 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #pragma once
6 
7 #include <cstdlib>
8 #include <functional>
9 #include <memory>
10 #include <optional>
11 #include <string>
12 #include <variant>
13 #include <vector>
14 
15 #include "Common/CommonTypes.h"
16 #include "Core/IOS/IOSC.h"
17 #include "DiscIO/Blob.h"
18 #include "DiscIO/Enums.h"
19 #include "DiscIO/VolumeDisc.h"
20 #include "DiscIO/VolumeWad.h"
21 
22 namespace File
23 {
24 class IOFile;
25 }
26 
27 struct RegionSetting
28 {
29   std::string area;
30   std::string video;
31   std::string game;
32   std::string code;
33 };
34 
35 class BootExecutableReader;
36 
37 struct BootParameters
38 {
39   struct Disc
40   {
41     std::string path;
42     std::unique_ptr<DiscIO::VolumeDisc> volume;
43     std::vector<std::string> auto_disc_change_paths;
44   };
45 
46   struct Executable
47   {
48     std::string path;
49     std::unique_ptr<BootExecutableReader> reader;
50   };
51 
52   struct NANDTitle
53   {
54     u64 id;
55   };
56 
57   struct IPL
58   {
59     explicit IPL(DiscIO::Region region_);
60     IPL(DiscIO::Region region_, Disc&& disc_);
61     std::string path;
62     DiscIO::Region region;
63     // It is possible to boot the IPL with a disc inserted (with "skip IPL" disabled).
64     std::optional<Disc> disc;
65   };
66 
67   struct DFF
68   {
69     std::string dff_path;
70   };
71 
72   static std::unique_ptr<BootParameters>
73   GenerateFromFile(std::string boot_path, const std::optional<std::string>& savestate_path = {});
74   static std::unique_ptr<BootParameters>
75   GenerateFromFile(std::vector<std::string> paths,
76                    const std::optional<std::string>& savestate_path = {});
77 
78   using Parameters = std::variant<Disc, Executable, DiscIO::VolumeWAD, NANDTitle, IPL, DFF>;
79   BootParameters(Parameters&& parameters_, const std::optional<std::string>& savestate_path_ = {});
80 
81   Parameters parameters;
82   std::optional<std::string> savestate_path;
83   bool delete_savestate = false;
84 };
85 
86 class CBoot
87 {
88 public:
89   static bool BootUp(std::unique_ptr<BootParameters> boot);
90 
91   // Tries to find a map file for the current game by looking first in the
92   // local user directory, then in the shared user directory.
93   //
94   // If existing_map_file is not nullptr and a map file exists, it is set to the
95   // path to the existing map file.
96   //
97   // If writable_map_file is not nullptr, it is set to the path to where a map
98   // file should be saved.
99   //
100   // Returns true if a map file exists, false if none could be found.
101   static bool FindMapFile(std::string* existing_map_file, std::string* writable_map_file);
102   static bool LoadMapFromFilename();
103 
104 private:
105   static bool DVDRead(const DiscIO::VolumeDisc& disc, u64 dvd_offset, u32 output_address,
106                       u32 length, const DiscIO::Partition& partition);
107   static bool DVDReadDiscID(const DiscIO::VolumeDisc& disc, u32 output_address);
108   static void RunFunction(u32 address);
109 
110   static void UpdateDebugger_MapLoaded();
111 
112   static bool Boot_WiiWAD(const DiscIO::VolumeWAD& wad);
113   static bool BootNANDTitle(u64 title_id);
114 
115   static void SetupMSR();
116   static void SetupBAT(bool is_wii);
117   static bool RunApploader(bool is_wii, const DiscIO::VolumeDisc& volume);
118   static bool EmulatedBS2_GC(const DiscIO::VolumeDisc& volume);
119   static bool EmulatedBS2_Wii(const DiscIO::VolumeDisc& volume);
120   static bool EmulatedBS2(bool is_wii, const DiscIO::VolumeDisc& volume);
121   static bool Load_BS2(const std::string& boot_rom_filename);
122 
123   static void SetupGCMemory();
124   static bool SetupWiiMemory(IOS::HLE::IOSC::ConsoleType console_type);
125 };
126 
127 class BootExecutableReader
128 {
129 public:
130   explicit BootExecutableReader(const std::string& file_name);
131   explicit BootExecutableReader(File::IOFile file);
132   explicit BootExecutableReader(std::vector<u8> buffer);
133   virtual ~BootExecutableReader();
134 
135   virtual u32 GetEntryPoint() const = 0;
136   virtual bool IsValid() const = 0;
137   virtual bool IsWii() const = 0;
138   virtual bool LoadIntoMemory(bool only_in_mem1 = false) const = 0;
139   virtual bool LoadSymbols() const = 0;
140 
141 protected:
142   std::vector<u8> m_bytes;
143 };
144 
145 struct StateFlags
146 {
147   void UpdateChecksum();
148   u32 checksum;
149   u8 flags;
150   u8 type;
151   u8 discstate;
152   u8 returnto;
153   u32 unknown[6];
154 };
155 
156 // Reads the state file from the NAND, then calls the passed update function to update the struct,
157 // and finally writes the updated state file to the NAND.
158 void UpdateStateFlags(std::function<void(StateFlags*)> update_function);
159 
160 /// Create title directories for the system menu (if needed).
161 ///
162 /// Normally, this is automatically done by ES when the System Menu is installed,
163 /// but we cannot rely on this because we don't require any system titles to be installed.
164 void CreateSystemMenuTitleDirs();
165