xcc_dirs.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. XCC Utilities and Library
  3. Copyright (C) 2000 Olaf van der Spek <[email protected]>
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "xcc_dirs.h"
  16. #include <boost/algorithm/string.hpp>
  17. #include <cassert>
  18. #include <windows.h>
  19. #include "reg_key.h"
  20. #include "string_conversion.h"
  21. #include "xcc_registry.h"
  22. bool g_enable_log = false;
  23. static string dune2_dir;
  24. static string td_primary_dir;
  25. static string td_secondary_dir;
  26. static string cd_dir;
  27. static string data_dir;
  28. static string ra_dir;
  29. static string dune2000_dir;
  30. static string ts_dir;
  31. static string ra2_dir;
  32. static string nox_dir;
  33. static string rg_dir;
  34. static string gr_dir;
  35. static string gr_zh_dir;
  36. static string ebfd_dir;
  37. static string bfme_dir;
  38. static string tw_dir;
  39. bool xcc_dirs::enable_log()
  40. {
  41. return g_enable_log;
  42. }
  43. string xcc_dirs::get_dir(t_game game)
  44. {
  45. switch (game)
  46. {
  47. case game_td:
  48. return td_primary_dir;
  49. case game_ra:
  50. return ra_dir;
  51. case game_ts:
  52. case game_ts_fs:
  53. return ts_dir;
  54. case game_dune2:
  55. return dune2_dir;
  56. case game_dune2000:
  57. return dune2000_dir;
  58. case game_ra2:
  59. case game_ra2_yr:
  60. return ra2_dir;
  61. case game_nox:
  62. return nox_dir;
  63. case game_rg:
  64. return rg_dir;
  65. case game_gr:
  66. return gr_dir;
  67. case game_gr_zh:
  68. return gr_zh_dir;
  69. case game_ebfd:
  70. return ebfd_dir;
  71. case game_bfme:
  72. return bfme_dir;
  73. case game_tw:
  74. return tw_dir;
  75. }
  76. assert(false);
  77. return "";
  78. }
  79. string xcc_dirs::get_exe(t_game game)
  80. {
  81. switch (game)
  82. {
  83. case game_td:
  84. return td_primary_dir + "c&c95.exe";
  85. case game_ra:
  86. return ra_dir + "ra95.exe";
  87. case game_ts:
  88. return ts_dir + "sun.exe";
  89. case game_dune2:
  90. return dune2_dir + "dune2.exe";
  91. case game_dune2000:
  92. return dune2000_dir + "dune2000.exe";
  93. case game_ra2:
  94. return ra2_dir + "ra2.exe";
  95. case game_nox:
  96. return nox_dir + "nox.exe";
  97. case game_ra2_yr:
  98. return ra2_dir + "ra2md.exe";
  99. case game_gr:
  100. return gr_dir + "generals.exe";
  101. case game_bfme:
  102. return bfme_dir + "lotrbfme.exe";
  103. }
  104. assert(false);
  105. return "";
  106. }
  107. string xcc_dirs::get_audio_mix(t_game game)
  108. {
  109. switch (game)
  110. {
  111. case game_ra2:
  112. return "audio.mix";
  113. case game_ra2_yr:
  114. return "audiomd.mix";
  115. }
  116. assert(false);
  117. return "";
  118. }
  119. string xcc_dirs::get_csf_fname(t_game game)
  120. {
  121. switch (game)
  122. {
  123. case game_ra2:
  124. return "ra2.csf";
  125. case game_ra2_yr:
  126. return "ra2md.csf";
  127. case game_gr:
  128. case game_gr_zh:
  129. return "data/english/generals.csf";
  130. }
  131. assert(false);
  132. return "";
  133. }
  134. static string get_suffix(t_game game)
  135. {
  136. return game == game_ra2_yr ? "md" : "";
  137. }
  138. string xcc_dirs::get_ecache_mix(t_game game, bool dir, int i)
  139. {
  140. return get_ecache_mix(game, dir, nwzl(2, i));
  141. }
  142. string xcc_dirs::get_ecache_mix(t_game game, bool dir, const string& s)
  143. {
  144. string r = "ecache" + get_suffix(game) + s + ".mix";
  145. if (dir)
  146. r = get_dir(game) + r;
  147. return r;
  148. }
  149. string xcc_dirs::get_expand_mix(t_game game, int i)
  150. {
  151. return get_expand_mix(game, nwzl(2, i));
  152. }
  153. string xcc_dirs::get_expand_mix(t_game game, const string& s)
  154. {
  155. return get_dir(game) + "expand" + get_suffix(game) + s + ".mix";
  156. }
  157. string xcc_dirs::get_language_mix(t_game game)
  158. {
  159. switch (game)
  160. {
  161. case game_ra2:
  162. return ra2_dir + "language.mix";
  163. case game_ra2_yr:
  164. return ra2_dir + "langmd.mix";
  165. case game_gr:
  166. return gr_dir + "english.big";
  167. case game_gr_zh:
  168. return gr_zh_dir + "englishzh.big";
  169. }
  170. assert(false);
  171. return "";
  172. }
  173. string xcc_dirs::get_local_mix(t_game game)
  174. {
  175. switch (game)
  176. {
  177. case game_ts:
  178. case game_ra2:
  179. return "local.mix";
  180. case game_ra2_yr:
  181. return "localmd.mix";
  182. }
  183. assert(false);
  184. return "";
  185. }
  186. string xcc_dirs::get_main_mix(t_game game)
  187. {
  188. switch (game)
  189. {
  190. case game_ra:
  191. return ra_dir + "redalert.mix";
  192. case game_ts:
  193. return ts_dir + "tibsun.mix";
  194. case game_ra2:
  195. return ra2_dir + "ra2.mix";
  196. case game_ra2_yr:
  197. return ra2_dir + "ra2md.mix";
  198. }
  199. assert(false);
  200. return "";
  201. }
  202. static void set_path(string s, string& path)
  203. {
  204. boost::to_lower(s);
  205. if (!s.empty() && s.back() != '\\')
  206. s += '\\';
  207. path = s;
  208. }
  209. void xcc_dirs::set_dir(t_game game, const string &s)
  210. {
  211. switch (game)
  212. {
  213. case game_td:
  214. set_path(s, td_primary_dir);
  215. break;
  216. case game_ra:
  217. set_path(s, ra_dir);
  218. break;
  219. case game_ts:
  220. set_path(s, ts_dir);
  221. break;
  222. case game_dune2:
  223. set_path(s, dune2_dir);
  224. break;
  225. case game_dune2000:
  226. set_path(s, dune2000_dir);
  227. break;
  228. case game_ra2:
  229. set_path(s, ra2_dir);
  230. break;
  231. case game_nox:
  232. set_path(s, nox_dir);
  233. break;
  234. case game_rg:
  235. set_path(s, rg_dir);
  236. break;
  237. case game_gr:
  238. set_path(s, gr_dir);
  239. break;
  240. case game_gr_zh:
  241. set_path(s, gr_zh_dir);
  242. break;
  243. case game_ebfd:
  244. set_path(s, ebfd_dir);
  245. break;
  246. case game_bfme:
  247. set_path(s, bfme_dir);
  248. break;
  249. case game_tw:
  250. set_path(s, tw_dir);
  251. break;
  252. default:
  253. assert(false);
  254. }
  255. }
  256. void xcc_dirs::set_td_secondary_dir(const string& s)
  257. {
  258. set_path(s, td_secondary_dir);
  259. }
  260. void xcc_dirs::set_cd_dir(const string& s)
  261. {
  262. set_path(s, cd_dir);
  263. }
  264. void xcc_dirs::set_data_dir(const string& s)
  265. {
  266. set_path(s, data_dir);
  267. }
  268. void xcc_dirs::reset_cd_dir()
  269. {
  270. int drive_map = GetLogicalDrives();
  271. char drive_root[] = "a:\\";
  272. for (int i = 0; i < 26; i++)
  273. {
  274. if (drive_map >> i & 1 && GetDriveTypeA(drive_root) == DRIVE_CDROM)
  275. {
  276. set_cd_dir(drive_root);
  277. break;
  278. }
  279. drive_root[0]++;
  280. }
  281. }
  282. void xcc_dirs::reset_data_dir()
  283. {
  284. set_data_dir(GetModuleFileName().get_path());
  285. }
  286. static void read_dir(const string& key, const string& value, t_game game)
  287. {
  288. Creg_key h;
  289. string s;
  290. if (xcc_dirs::get_dir(game).empty()
  291. && ERROR_SUCCESS == h.open(HKEY_LOCAL_MACHINE, key, KEY_QUERY_VALUE)
  292. && ERROR_SUCCESS == h.query_value(value, s))
  293. xcc_dirs::set_dir(game, Cfname(s).get_path());
  294. }
  295. void xcc_dirs::load_from_registry()
  296. {
  297. Creg_key kh_base;
  298. if (!Cxcc_registry::get_base_key(kh_base))
  299. {
  300. string s;
  301. if (ERROR_SUCCESS == kh_base.query_value("dune2_dir", s))
  302. set_dir(game_dune2, s);
  303. if (ERROR_SUCCESS == kh_base.query_value("dir1", s))
  304. set_dir(game_td, s);
  305. if (ERROR_SUCCESS == kh_base.query_value("dir2", s))
  306. set_td_secondary_dir(s);
  307. if (ERROR_SUCCESS == kh_base.query_value("ra_dir", s))
  308. set_dir(game_ra, s);
  309. if (ERROR_SUCCESS == kh_base.query_value("cd_dir", s))
  310. set_cd_dir(s);
  311. if (ERROR_SUCCESS == kh_base.query_value("data_dir", s))
  312. set_data_dir(s);
  313. if (ERROR_SUCCESS == kh_base.query_value("enable_log", s))
  314. g_enable_log = true;
  315. }
  316. if (cd_dir.empty())
  317. reset_cd_dir();
  318. if (data_dir.empty())
  319. reset_data_dir();
  320. read_dir("Software\\Westwood\\Dune 2", "InstallPath", game_dune2);
  321. read_dir("Software\\Westwood\\Command & Conquer Windows 95 Edition", "InstallPath", game_td);
  322. read_dir("Software\\Westwood\\Red Alert Windows 95 Edition", "InstallPath", game_ra);
  323. read_dir("Software\\Westwood\\Dune 2000", "InstallPath", game_dune2000);
  324. read_dir("Software\\Westwood\\Tiberian Sun", "InstallPath", game_ts);
  325. read_dir("Software\\Westwood\\Red Alert 2", "InstallPath", game_ra2);
  326. read_dir("Software\\Westwood\\Nox", "InstallPath", game_nox);
  327. read_dir("Software\\Westwood\\Renegade", "InstallPath", game_rg);
  328. read_dir("Software\\Westwood\\Emperor", "InstallPath", game_ebfd);
  329. /*
  330. read_dir("Software\\Electronic Arts\\EA Games\\Generals", "InstallPath", game_gr);
  331. read_dir("Software\\Electronic Arts\\EA Games\\Command and Conquer Generals Zero Hour", "InstallPath", game_gr_zh);
  332. read_dir("Software\\Electronic Arts\\EA Games\\The Battle for Middle-earth", "InstallPath", game_bfme);
  333. read_dir("Software\\Electronic Arts\\Electronic Arts\\Command and Conquer 3", "InstallPath", game_tw);
  334. */
  335. }
  336. void xcc_dirs::save_to_registry()
  337. {
  338. Creg_key kh_base;
  339. if (Cxcc_registry::get_base_key(kh_base))
  340. return;
  341. kh_base.set_value("dune2_dir", dune2_dir);
  342. kh_base.set_value("dir1", td_primary_dir);
  343. kh_base.set_value("dir2", td_secondary_dir);
  344. kh_base.set_value("ra_dir", ra_dir);
  345. };
  346. string xcc_dirs::find_file(Cfname s)
  347. {
  348. if (!s.get_path().empty() || s.exists())
  349. return s;
  350. s.set_path(td_primary_dir);
  351. if (s.exists())
  352. return s;
  353. s.set_path(td_secondary_dir);
  354. if (s.exists())
  355. return s;
  356. s.set_path(ra_dir);
  357. if (s.exists())
  358. return s;
  359. s.set_path(ts_dir);
  360. if (s.exists())
  361. return s;
  362. s.set_path(ra2_dir);
  363. if (s.exists())
  364. return s;
  365. s.set_path(cd_dir);
  366. return s;
  367. }
  368. bool xcc_dirs::is_available(t_game game)
  369. {
  370. return Cfname(get_exe(game)).exists();
  371. }
  372. const string& xcc_dirs::get_td_secondary_dir()
  373. {
  374. return td_secondary_dir;
  375. }
  376. const string& xcc_dirs::get_cd_dir()
  377. {
  378. return cd_dir;
  379. }
  380. const string& xcc_dirs::get_data_dir()
  381. {
  382. return data_dir;
  383. }