prefs.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #include <io.h> // for _chmod()
  5. #include "prefs.h"
  6. #include "gamesound.h"
  7. #include "MissionGui.h"
  8. #include "soundSys.h"
  9. #include "..\resource.h"
  10. extern SoundSystem *sndSystem;
  11. extern long DigitalMasterVolume;
  12. extern long MusicVolume;
  13. extern long sfxVolume;
  14. extern long RadioVolume;
  15. extern long BettyVolume;
  16. extern bool useShadows;
  17. extern bool useLocalShadows;
  18. extern bool useWaterInterestTexture;
  19. extern bool useUnlimitedAmmo;
  20. extern long GameDifficulty;
  21. extern long renderer;
  22. extern long resolution;
  23. extern long gammaLevel;
  24. extern bool useLeftRightMouseProfile;
  25. extern bool useNonWeaponEffects;
  26. extern bool useHighObjectDetail;
  27. extern long GameVisibleVertices;
  28. extern volatile bool mc2UseAsyncMouse; //Should mouse draw and update in separate thread?
  29. extern DWORD gEnableDetailTexture;
  30. CPrefs::CPrefs() {
  31. DigitalMasterVolume = 255;
  32. MusicVolume = 64;
  33. sfxVolume = 64;
  34. RadioVolume = 64;
  35. BettyVolume = 64;
  36. useShadows = true;
  37. useWaterInterestTexture = true;
  38. useHighObjectDetail = true;
  39. GameDifficulty = 0;
  40. useUnlimitedAmmo = true;
  41. renderer = 0;
  42. resolution = 1;
  43. fullScreen = false;
  44. gammaLevel = 0;
  45. useLeftRightMouseProfile = true; // if false, use old style commands
  46. for ( int i = 0; i < 10; i++ )
  47. playerName[i][0] = 0;
  48. for (i = 0; i < 10; i++ )
  49. ipAddresses[i][0] = 0;
  50. baseColor = 0xffff7e00;
  51. highlightColor = 0xffff7e00;
  52. faction = 0;
  53. insigniaFile[0] = 0;
  54. for ( i = 0; i < 10; i++ )
  55. unitName[i][0] = 0;
  56. #if 0
  57. FilterState = gos_FilterNone;
  58. TERRAIN_TXM_SIZE = 64;
  59. ObjectTextureSize = 128;
  60. useRealLOS = true;
  61. doubleClickThreshold = 0.2f;
  62. dragThreshold = 10;
  63. BaseVertexColor = 0x00000000; //This color is applied to all vertices in game as Brightness correction.
  64. #endif
  65. }
  66. int CPrefs::load( const char* pFileName ) {
  67. long result = 0;
  68. FullPathFileName prefsPathname;
  69. prefsPathname.init("./",pFileName,".cfg");
  70. FitIniFilePtr prefsFile = new FitIniFile;
  71. #ifdef _DEBUG
  72. long prefsOpenResult =
  73. #endif
  74. prefsFile->open(prefsPathname);
  75. gosASSERT (prefsOpenResult == NO_ERR);
  76. {
  77. #ifdef _DEBUG
  78. long prefsBlockResult =
  79. #endif
  80. prefsFile->seekBlock("MechCommander2");
  81. gosASSERT(prefsBlockResult == NO_ERR);
  82. {
  83. // store volume settings in global variable since soundsystem
  84. // does not exist yet. These will be set in SoundSystem::init()
  85. result = prefsFile->readIdLong("DigitalMasterVolume",DigitalMasterVolume);
  86. if (result != NO_ERR)
  87. DigitalMasterVolume = 255;
  88. result = prefsFile->readIdLong("MusicVolume",MusicVolume);
  89. if (result != NO_ERR)
  90. MusicVolume = 64;
  91. result = prefsFile->readIdLong("RadioVolume",RadioVolume);
  92. if (result != NO_ERR)
  93. RadioVolume = 64;
  94. result = prefsFile->readIdLong("SFXVolume",sfxVolume);
  95. if (result != NO_ERR)
  96. sfxVolume = 64;
  97. result = prefsFile->readIdLong("BettyVolume",BettyVolume);
  98. if (result != NO_ERR)
  99. BettyVolume = 64;
  100. result = prefsFile->readIdBoolean( "Shadows", useShadows);
  101. if (result != NO_ERR)
  102. useShadows = true;
  103. result = prefsFile->readIdBoolean( "DetailTexture", useWaterInterestTexture);
  104. if (result != NO_ERR)
  105. useWaterInterestTexture = true;
  106. result = prefsFile->readIdBoolean( "HighObjectDetail", useHighObjectDetail );
  107. if ( result != NO_ERR )
  108. useHighObjectDetail = true;
  109. result = prefsFile->readIdLong("Difficulty",GameDifficulty);
  110. if (result != NO_ERR)
  111. GameDifficulty = 1;
  112. result = prefsFile->readIdBoolean("UnlimitedAmmo",useUnlimitedAmmo);
  113. if (result != NO_ERR)
  114. useUnlimitedAmmo = true;
  115. result = prefsFile->readIdLong("Rasterizer",renderer);
  116. if (result != NO_ERR)
  117. renderer = 0;
  118. if ((renderer < 0) || (renderer > 3))
  119. renderer = 0;
  120. //Force use of video card which is above min spec.
  121. // Used ONLY if they are using a below minSpec Primary with an above minSpec secondary.
  122. if ((renderer >= 0) && (renderer < 3) &&
  123. (gos_GetMachineInformation(gos_Info_GetDeviceLocalMemory, renderer) +
  124. gos_GetMachineInformation(gos_Info_GetDeviceAGPMemory, renderer)) < 6291456)
  125. {
  126. long testRender = 0;
  127. while (testRender < 3)
  128. {
  129. if ((gos_GetMachineInformation(gos_Info_GetDeviceLocalMemory, testRender) +
  130. gos_GetMachineInformation(gos_Info_GetDeviceAGPMemory, testRender)) >= 6291456)
  131. break;
  132. testRender++;
  133. }
  134. if (testRender == 3)
  135. {
  136. //No video card in the machine above MinSpec. Just set it to the first one.
  137. renderer = 0;
  138. }
  139. }
  140. result = prefsFile->readIdLong("Resolution",resolution);
  141. if (result != NO_ERR)
  142. resolution = 1;
  143. result = prefsFile->readIdBoolean("FullScreen",fullScreen);
  144. if (result != NO_ERR)
  145. fullScreen = false;
  146. result = prefsFile->readIdLong("Brightness",gammaLevel);
  147. if (result != NO_ERR)
  148. gammaLevel = 0;
  149. result = prefsFile->readIdBoolean( "useLeftRightMouseProfile", useLeftRightMouseProfile );
  150. if ( result != NO_ERR )
  151. useLeftRightMouseProfile = true;
  152. char blockName[64];
  153. for ( int i = 0; i < 10; i++ )
  154. {
  155. sprintf( blockName, "PlayerName%ld", i );
  156. result = prefsFile->readIdString( blockName, &playerName[i][0], 255 );
  157. if ( result != NO_ERR && i == 0 )
  158. {
  159. result = prefsFile->readIdString( "PlayerName", &playerName[0][0], 255 );
  160. result = prefsFile->readIdString( "UnitName", &unitName[0][0], 255 );
  161. break;
  162. }
  163. sprintf( blockName, "IPAddress%ld", i );
  164. result = prefsFile->readIdString( blockName, &ipAddresses[i][0], 255 );
  165. sprintf( blockName, "UnitName%ld", i );
  166. result = prefsFile->readIdString( blockName, &unitName[i][0], 255 );
  167. }
  168. result = prefsFile->readIdLong( "BaseColor", baseColor );
  169. if ( result != NO_ERR )
  170. baseColor = 0xffff7e00;
  171. result = prefsFile->readIdLong( "Highlightcolor", highlightColor );
  172. if ( result != NO_ERR )
  173. highlightColor = 0xffff7e00;
  174. result = prefsFile->readIdLong( "faction", faction );
  175. result = prefsFile->readIdString( "InsigniaFile", insigniaFile, 255 );
  176. result = prefsFile->readIdBoolean( "PilotVideos", pilotVideos );
  177. if ( result != NO_ERR )
  178. {
  179. pilotVideos = true;
  180. }
  181. result = prefsFile->readIdBoolean( "UseLocalShadows", useLocalShadows );
  182. if ( result != NO_ERR )
  183. {
  184. useLocalShadows = true;
  185. }
  186. result = prefsFile->readIdBoolean( "UseNonWeaponEffects", useNonWeaponEffects );
  187. if ( result != NO_ERR )
  188. {
  189. useNonWeaponEffects = 0;
  190. }
  191. result = prefsFile->readIdBoolean( "AsyncMouse", asyncMouse );
  192. if ( result != NO_ERR )
  193. asyncMouse = 0;
  194. result = prefsFile->readIdLong( "FogPos", fogPos );
  195. if ( result != NO_ERR )
  196. {
  197. fogPos = 50;
  198. }
  199. result = prefsFile->readIdChar( "BitDepth", bitDepth );
  200. if ( result != NO_ERR )
  201. bitDepth = 0;
  202. if (bitDepth && (renderer == 3))
  203. bitDepth = 0;
  204. result = prefsFile->readIdBoolean( "SaveTranscripts", saveTranscripts );
  205. result = prefsFile->readIdBoolean( "Tutorials", tutorials );
  206. if ( result != NO_ERR )
  207. tutorials = true;
  208. }
  209. }
  210. #ifndef VIEWER
  211. MissionInterfaceManager::loadHotKeys( *prefsFile);
  212. #endif
  213. prefsFile->close();
  214. delete prefsFile;
  215. prefsFile = NULL;
  216. return 0;
  217. }
  218. int CPrefs::save() {
  219. char backupPath[256];
  220. char originalPath[256];
  221. strcpy( originalPath, "options.cfg" );
  222. strcpy( backupPath, originalPath );
  223. strcat( backupPath,".old" );
  224. _chmod(originalPath, _S_IWRITE);
  225. _chmod(backupPath, _S_IWRITE);
  226. remove(backupPath);
  227. rename(originalPath, backupPath);
  228. //MoveFileEx(originalPath, backupPath, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH);
  229. FitIniFilePtr prefsFile = new FitIniFile;
  230. int result = prefsFile->create( (char*)originalPath );
  231. if (result != NO_ERR)
  232. {
  233. gosASSERT( false );
  234. return -1;
  235. }
  236. {
  237. #ifdef _DEBUG
  238. long prefsBlockResult =
  239. #endif
  240. prefsFile->writeBlock("MechCommander2");
  241. gosASSERT(prefsBlockResult == strlen("\r\n[") + strlen("MechCommander2") + strlen("]\r\n"));
  242. {
  243. result = prefsFile->writeIdLong("DigitalMasterVolume",DigitalMasterVolume);
  244. result = prefsFile->writeIdLong("MusicVolume",MusicVolume);
  245. result = prefsFile->writeIdLong("RadioVolume",RadioVolume);
  246. result = prefsFile->writeIdLong("SFXVolume",sfxVolume);
  247. result = prefsFile->writeIdLong("BettyVolume",BettyVolume);
  248. result = prefsFile->writeIdBoolean( "Shadows", useShadows );
  249. result = prefsFile->writeIdBoolean( "DetailTexture", useWaterInterestTexture );
  250. result = prefsFile->writeIdBoolean( "HighObjectDetail", useHighObjectDetail );
  251. result = prefsFile->writeIdLong("Difficulty",GameDifficulty);
  252. result = prefsFile->writeIdBoolean("UnlimitedAmmo",useUnlimitedAmmo);
  253. result = prefsFile->writeIdLong("Rasterizer",renderer);
  254. result = prefsFile->writeIdLong("Resolution",resolution);
  255. result = prefsFile->writeIdBoolean("FullScreen",fullScreen);
  256. result = prefsFile->writeIdLong("Brightness",gammaLevel);
  257. result = prefsFile->writeIdBoolean( "useLeftRightMouseProfile", useLeftRightMouseProfile );
  258. char blockName[64];
  259. for ( int i = 0; i < 10; i++ )
  260. {
  261. sprintf( blockName, "PlayerName%ld", i );
  262. result = prefsFile->writeIdString( blockName, &playerName[i][0] );
  263. sprintf( blockName, "UnitName%ld", i );
  264. result = prefsFile->writeIdString( blockName, &unitName[i][0] );
  265. sprintf( blockName, "IPAddress%ld", i );
  266. result = prefsFile->writeIdString( blockName, &ipAddresses[i][0] );
  267. }
  268. result = prefsFile->writeIdLong( "BaseColor", baseColor );
  269. result = prefsFile->writeIdLong( "Highlightcolor", highlightColor );
  270. result = prefsFile->writeIdLong( "faction", faction );
  271. result = prefsFile->writeIdString( "InsigniaFile", insigniaFile );
  272. result = prefsFile->writeIdBoolean( "PilotVideos", pilotVideos );
  273. result = prefsFile->writeIdBoolean( "UseLocalShadows", useLocalShadows );
  274. result = prefsFile->writeIdBoolean( "UseNonWeaponEffects", useNonWeaponEffects );
  275. result = prefsFile->writeIdBoolean( "AsyncMouse", asyncMouse );
  276. result = prefsFile->writeIdLong( "FogPos", fogPos );
  277. result = prefsFile->writeIdChar( "BitDepth", bitDepth );
  278. result = prefsFile->writeIdBoolean( "SaveTranscripts", saveTranscripts );
  279. result = prefsFile->writeIdBoolean( "Tutorials", tutorials );
  280. }
  281. }
  282. #ifndef VIEWER
  283. MissionInterfaceManager::saveHotKeys( *prefsFile);
  284. #endif
  285. prefsFile->close();
  286. delete prefsFile;
  287. prefsFile = NULL;
  288. return 0;
  289. }
  290. int CPrefs::applyPrefs(bool applyRes) {
  291. if (soundSystem) {
  292. /*soundSystem doesn't seem to do anything*/
  293. soundSystem->setDigitalMasterVolume(this->DigitalMasterVolume);
  294. soundSystem->setSFXVolume(this->sfxVolume);
  295. soundSystem->setRadioVolume(this->RadioVolume);
  296. soundSystem->setMusicVolume(this->MusicVolume);
  297. soundSystem->setBettyVolume(this->BettyVolume);
  298. }
  299. if (sndSystem) {
  300. sndSystem->setDigitalMasterVolume(this->DigitalMasterVolume);
  301. sndSystem->setSFXVolume(this->sfxVolume);
  302. sndSystem->setRadioVolume(this->RadioVolume);
  303. sndSystem->setMusicVolume(this->MusicVolume);
  304. sndSystem->setBettyVolume(this->BettyVolume);
  305. }
  306. ::useShadows = this->useShadows;
  307. ::useLocalShadows = this->useLocalShadows;
  308. ::useWaterInterestTexture = this->useWaterInterestTexture;
  309. ::GameDifficulty = this->GameDifficulty;
  310. ::useUnlimitedAmmo = this->useUnlimitedAmmo;
  311. ::renderer = this->renderer;
  312. ::resolution = this->resolution;
  313. ::gammaLevel = this->gammaLevel;
  314. mc2UseAsyncMouse = this->asyncMouse;
  315. ::useLeftRightMouseProfile = this->useLeftRightMouseProfile;
  316. ::useNonWeaponEffects = this->useNonWeaponEffects;
  317. ::useHighObjectDetail = this->useHighObjectDetail;
  318. int bitDepth = this->bitDepth ? 32 : 16;
  319. //Play with the fog distance.
  320. float fogPercent = float(fogPos) / 100.0f;
  321. Camera::MaxClipDistance = 3000.0f + (2000.0f * fogPercent);
  322. Camera::MinHazeDistance = 2000.0f + (2000.0f * fogPercent);
  323. ::GameVisibleVertices = 30 + (30 * fogPercent);
  324. if (land)
  325. {
  326. land->resetVisibleVertices(::GameVisibleVertices);
  327. land->update();
  328. }
  329. if ( applyRes )
  330. {
  331. long localRenderer = renderer;
  332. if ((renderer != 0) && (renderer != 3))
  333. localRenderer = 0;
  334. bool localFullScreen = fullScreen;
  335. bool localWindow = !fullScreen;
  336. if (Environment.fullScreen && fullScreen)
  337. localFullScreen = false;
  338. switch (resolution)
  339. {
  340. case 0: //640by480
  341. if ((gos_GetMachineInformation( gos_Info_ValidMode, renderer, 640, 480, bitDepth) == 0) && (bitDepth == 32))
  342. bitDepth = 16;
  343. if (renderer == 3)
  344. gos_SetScreenMode(640,480,bitDepth,0,0,0,true,localFullScreen,0,localWindow,0,localRenderer);
  345. else
  346. gos_SetScreenMode(640,480,bitDepth,renderer,0,0,0,localFullScreen,0,localWindow,0,localRenderer);
  347. break;
  348. case 1: //800by600
  349. if ((gos_GetMachineInformation( gos_Info_ValidMode, renderer, 800, 600, bitDepth) == 0) && (bitDepth == 32))
  350. bitDepth = 16;
  351. if (renderer == 3)
  352. gos_SetScreenMode(800,600,bitDepth,0,0,0,true,localFullScreen,0,localWindow,0,localRenderer);
  353. else
  354. gos_SetScreenMode(800,600,bitDepth,renderer,0,0,0,localFullScreen,0,localWindow,0,localRenderer);
  355. break;
  356. case 2: //1024by768
  357. if ((gos_GetMachineInformation( gos_Info_ValidMode, renderer, 1024, 768, bitDepth) == 0) && (bitDepth == 32))
  358. bitDepth = 16;
  359. if (renderer == 3)
  360. gos_SetScreenMode(1024,768,bitDepth,0,0,0,true,localFullScreen,0,localWindow,0,localRenderer);
  361. else
  362. gos_SetScreenMode(1024,768,bitDepth,renderer,0,0,0,localFullScreen,0,localWindow,0,localRenderer);
  363. break;
  364. case 3: //1280by1024
  365. if ((gos_GetMachineInformation( gos_Info_ValidMode, renderer, 1280, 1024, bitDepth) == 0) && (bitDepth == 32))
  366. bitDepth = 16;
  367. if (renderer == 3)
  368. gos_SetScreenMode(1280,1024,bitDepth,0,0,0,true,localFullScreen,0,localWindow,0,localRenderer);
  369. else
  370. gos_SetScreenMode(1280,1024,bitDepth,renderer,0,0,0,localFullScreen,0,localWindow,0,localRenderer);
  371. break;
  372. case 4: //1600by1200
  373. if ((gos_GetMachineInformation( gos_Info_ValidMode, renderer, 1600, 1200, bitDepth) == 0) && (bitDepth == 32))
  374. bitDepth = 16;
  375. if (renderer == 3)
  376. gos_SetScreenMode(1600,1200,16,0,0,0,true,localFullScreen,0,localWindow,0,localRenderer);
  377. else
  378. gos_SetScreenMode(1600,1200,16,renderer,0,0,0,localFullScreen,0,localWindow,0,localRenderer);
  379. break;
  380. }
  381. }
  382. return 0;
  383. }
  384. void CPrefs::setNewName( const char* pNewName )
  385. {
  386. if ( !pNewName )
  387. return;
  388. // check and see if this name is already in here
  389. for ( int i = 0; i < 10; i++ )
  390. {
  391. if ( !stricmp( pNewName, playerName[i] ) )
  392. {
  393. // found the same one so now we just shuffle
  394. for ( int j = i; j < 9; j++ )
  395. {
  396. strcpy( playerName[j], playerName[j+1] );
  397. }
  398. memmove( playerName[1], playerName[0], sizeof( char ) * 9 * 256 );
  399. strcpy( playerName[0], pNewName );
  400. break;
  401. }
  402. else if ( !strlen( playerName[i] ) )
  403. {
  404. // found the last one...
  405. memmove( playerName[1], playerName[0], sizeof( char ) * 9 * 256 );
  406. strcpy( playerName[0], pNewName );
  407. break;
  408. }
  409. }
  410. if ( i == 10 )
  411. {
  412. memmove( playerName[1], playerName[0], sizeof( char ) * 9 * 256 );
  413. strcpy( playerName[0], pNewName );
  414. }
  415. }
  416. void CPrefs::setNewIP( const char* pNewIP )
  417. {
  418. if ( !pNewIP )
  419. return;
  420. // check and see if this name is already in here
  421. for ( int i = 0; i < 10; i++ )
  422. {
  423. if ( !stricmp( pNewIP, ipAddresses[i] ) )
  424. {
  425. // found the same one so now we just shuffle
  426. for ( int j = i; j < 9; j++ )
  427. {
  428. strcpy( ipAddresses[j], ipAddresses[j+1] );
  429. }
  430. memmove( ipAddresses[1], ipAddresses[0], sizeof( char ) * 9 * 24 );
  431. strcpy( ipAddresses[0], pNewIP );
  432. break;
  433. }
  434. else if ( !strlen( ipAddresses[i] ) )
  435. {
  436. // found the last one...
  437. memmove( ipAddresses[1], ipAddresses[0], sizeof( char ) * 9 * 24 );
  438. strcpy( ipAddresses[0], pNewIP );
  439. break;
  440. }
  441. }
  442. }
  443. void CPrefs::setNewUnit( const char* pNewUnit )
  444. {
  445. if ( !pNewUnit )
  446. return;
  447. // check and see if this name is already in here
  448. for ( int i = 0; i < 10; i++ )
  449. {
  450. if ( !stricmp( pNewUnit, unitName[i] ) )
  451. {
  452. // found the same one so now we just shuffle
  453. for ( int j = i; j < 9; j++ )
  454. {
  455. strcpy( unitName[j], unitName[j+1] );
  456. }
  457. memmove( unitName[1], unitName[0], sizeof( char ) * 9 * 256 );
  458. strcpy( unitName[0], pNewUnit );
  459. break;
  460. }
  461. else if ( !strlen( unitName[i] ) )
  462. {
  463. // found the last one...
  464. memmove( unitName[1], unitName[0], sizeof( char ) * 9 * 256 );
  465. strcpy( unitName[0], pNewUnit );
  466. break;
  467. }
  468. }
  469. if ( i == 10 )
  470. {
  471. memmove( unitName[1], unitName[0], sizeof( char ) * 9 * 256 );
  472. strcpy( unitName[0], pNewUnit );
  473. }
  474. }