xb_settings.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. #include "xb_settings.h"
  2. #include <xtl.h>
  3. #include "../game/q_shared.h"
  4. #include "qcommon.h"
  5. #define SETTINGS_VERSION 0x00082877
  6. #define SETTINGS_DIRNAME "Settings"
  7. #define SETTINGS_FILENAME "settings.dat"
  8. #define SETTINGS_IMAGE "saveimage.xbx"
  9. #define SETTINGS_IMAGE_SRC "d:\\base\\media\\settings.xbx"
  10. // The one copy of Settings:
  11. XBSettings Settings;
  12. const DWORD settingsSize = sizeof(Settings);
  13. const DWORD sigSize = sizeof(XCALCSIG_SIGNATURE);
  14. // This isn't user data, don't put it in XBSettings!
  15. enum XBSettingsStatus
  16. {
  17. SETTINGS_OK, // Everything is ok
  18. SETTINGS_MISSING, // File is not on disk
  19. SETTINGS_CORRUPT, // File on disk is corrupt
  20. SETTINGS_FAILED, // General error
  21. };
  22. XBSettingsStatus SettingsStatus;
  23. bool settingsDisabled = false;
  24. const char *buttonConfigStrings[3] = {
  25. "weaponsbias",
  26. "forcebias",
  27. "southpaw",
  28. };
  29. const char *triggerConfigStrings[2] = {
  30. "default",
  31. "southpaw",
  32. };
  33. XBSettings::XBSettings( void )
  34. {
  35. version = SETTINGS_VERSION;
  36. // Defaults:
  37. invertAim[0] = invertAim[1] = false;
  38. thumbstickMode[0] = thumbstickMode[1] = 0;
  39. buttonMode[0] = buttonMode[1] = 0;
  40. triggerMode[0] = triggerMode[1] = 0;
  41. rumble[0] = rumble[1] = 1;
  42. autolevel[0] = autolevel[0] = 0;
  43. autoswitch[0] = autoswitch[1] = 1;
  44. sensitivityX[0] = sensitivityX[1] = 2.0f;
  45. sensitivityY[0] = sensitivityY[1] = 2.0f;
  46. hotswapSP[0] = hotswapSP[1] = hotswapSP[2] = -1;
  47. hotswapMP[0] = hotswapMP[1] = -1;
  48. hotswapMP[2] = hotswapMP[3] = -1;
  49. effectsVolume = 1.0f;
  50. musicVolume = 0.25f;
  51. voiceVolume = 1.0f;
  52. brightness = 6.0f;
  53. subtitles = 0;
  54. #ifdef XBOX_DEMO
  55. // Demo has no foreign audio, so we turn subtitles on if Dash language is FR/GE
  56. DWORD dwLang = XGetLanguage();
  57. if( dwLang == XC_LANGUAGE_FRENCH || dwLang == XC_LANGUAGE_GERMAN )
  58. subtitles = 1;
  59. #endif
  60. voiceMode = 2;
  61. voiceMask = 0;
  62. appearOffline = 0;
  63. #ifdef XBOX_DEMO
  64. Disable(); // Ensure that we never try to load/save settings in the demo
  65. #endif
  66. }
  67. // Write the current stored settings to the HD:
  68. bool XBSettings::Save( void )
  69. {
  70. // Do nothing if user chose "Continue Without Saving"
  71. if( settingsDisabled )
  72. return true;
  73. char settingsPath[128];
  74. char *pathEnd;
  75. DWORD dwWritten;
  76. // Build the settings directory:
  77. unsigned short wideName[128];
  78. mbstowcs( wideName, SETTINGS_DIRNAME, sizeof(wideName) );
  79. // Open/create the settings directory:
  80. if (XCreateSaveGame( "U:\\", wideName, OPEN_ALWAYS, 0, settingsPath, sizeof(settingsPath) ) != ERROR_SUCCESS )
  81. {
  82. SettingsStatus = SETTINGS_FAILED;
  83. return false;
  84. }
  85. // Build path to settings file:
  86. pathEnd = settingsPath + strlen( settingsPath );
  87. strcpy( pathEnd, SETTINGS_FILENAME );
  88. // Open/create the settings file:
  89. HANDLE hFile = CreateFile( settingsPath, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  90. if( hFile == INVALID_HANDLE_VALUE )
  91. {
  92. SettingsStatus = SETTINGS_FAILED;
  93. return false;
  94. }
  95. // Write the data:
  96. if( !WriteFile( hFile, this, settingsSize, &dwWritten, NULL ) || (dwWritten != settingsSize) )
  97. {
  98. SettingsStatus = SETTINGS_FAILED;
  99. CloseHandle( hFile );
  100. return false;
  101. }
  102. // Sign the data:
  103. XCALCSIG_SIGNATURE xsig;
  104. if( !Sign( &xsig ) )
  105. {
  106. SettingsStatus = SETTINGS_FAILED;
  107. CloseHandle( hFile );
  108. return false;
  109. }
  110. // Write signature:
  111. if( !WriteFile( hFile, &xsig, sigSize, &dwWritten, NULL ) || (dwWritten != sigSize) )
  112. {
  113. SettingsStatus = SETTINGS_FAILED;
  114. CloseHandle( hFile );
  115. return false;
  116. }
  117. // Truncate and close file:
  118. SetEndOfFile( hFile );
  119. CloseHandle( hFile );
  120. // Copy the save image over:
  121. strcpy( pathEnd, SETTINGS_IMAGE );
  122. CopyFile( SETTINGS_IMAGE_SRC, settingsPath, FALSE );
  123. return true;
  124. }
  125. // Read saved settings from the HD:
  126. bool XBSettings::Load( void )
  127. {
  128. // Do nothing if user chose "Continue Without Saving"
  129. if( settingsDisabled )
  130. return true;
  131. char settingsPath[128];
  132. char *pathEnd;
  133. DWORD dwRead;
  134. // Build the settings directory:
  135. unsigned short wideName[128];
  136. mbstowcs( wideName, SETTINGS_DIRNAME, sizeof(wideName) );
  137. // Open the settings directory:
  138. if( XCreateSaveGame( "U:\\", wideName, OPEN_EXISTING, 0, settingsPath, sizeof(settingsPath) ) != ERROR_SUCCESS )
  139. {
  140. SettingsStatus = SETTINGS_MISSING;
  141. return false;
  142. }
  143. // Build path to settings file:
  144. pathEnd = settingsPath + strlen( settingsPath );
  145. strcpy( pathEnd, SETTINGS_FILENAME );
  146. HANDLE hFile = CreateFile( settingsPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  147. if( hFile == INVALID_HANDLE_VALUE )
  148. {
  149. SettingsStatus = SETTINGS_CORRUPT;
  150. return false;
  151. }
  152. // Verify file size:
  153. if( GetFileSize( hFile, NULL ) != (settingsSize + sigSize) )
  154. {
  155. SettingsStatus = SETTINGS_CORRUPT;
  156. CloseHandle( hFile );
  157. return false;
  158. }
  159. // Temp struct to read data into:
  160. XBSettings temp;
  161. if( !ReadFile( hFile, &temp, settingsSize, &dwRead, NULL ) || (dwRead != settingsSize) )
  162. {
  163. SettingsStatus = SETTINGS_CORRUPT;
  164. CloseHandle( hFile );
  165. return false;
  166. }
  167. // Calculate signature over the read-in data:
  168. XCALCSIG_SIGNATURE xsig;
  169. if( !temp.Sign( &xsig ) )
  170. {
  171. SettingsStatus = SETTINGS_CORRUPT;
  172. CloseHandle( hFile );
  173. return false;
  174. }
  175. // Read in stored signature:
  176. XCALCSIG_SIGNATURE storedSig;
  177. if( !ReadFile( hFile, &storedSig, sigSize, &dwRead, NULL ) || (dwRead != sigSize) )
  178. {
  179. SettingsStatus = SETTINGS_CORRUPT;
  180. CloseHandle( hFile );
  181. return false;
  182. }
  183. // We're done with the file:
  184. CloseHandle( hFile );
  185. // Compare signatures:
  186. if( memcmp( &xsig, &storedSig, sigSize ) != 0 )
  187. {
  188. SettingsStatus = SETTINGS_CORRUPT;
  189. return false;
  190. }
  191. // Lastly, verify that the version number is right:
  192. if( temp.version != SETTINGS_VERSION )
  193. {
  194. SettingsStatus = SETTINGS_CORRUPT;
  195. return false;
  196. }
  197. // OK. The data checks out!
  198. *this = temp;
  199. // TODO: Range-check all the values?
  200. return true;
  201. }
  202. void XBSettings::Delete( void )
  203. {
  204. // Build the settings directory:
  205. unsigned short wideName[128];
  206. mbstowcs( wideName, SETTINGS_DIRNAME, sizeof(wideName) );
  207. // Delete the game:
  208. XDeleteSaveGame( "U:\\", wideName );
  209. }
  210. bool XBSettings::Corrupt( void )
  211. {
  212. return (SettingsStatus == SETTINGS_CORRUPT);
  213. }
  214. bool XBSettings::Missing( void )
  215. {
  216. return (SettingsStatus == SETTINGS_MISSING);
  217. }
  218. // Copy all stored settings into cvars
  219. void XBSettings::SetAll( void )
  220. {
  221. Cvar_SetValue( "m_pitch", invertAim[0] ? 0.022f : -0.022f );
  222. Cvar_SetValue( "ui_thumbStickMode", thumbstickMode[0] );
  223. Cvar_Set( "ui_buttonconfig", buttonConfigStrings[buttonMode[0]] );
  224. Cbuf_ExecuteText( EXEC_APPEND, va("exec cfg/spbuttonConfig%d.cfg\n", buttonMode[0]) );
  225. Cvar_Set( "ui_triggerconfig", triggerConfigStrings[triggerMode[0]] );
  226. Cbuf_ExecuteText( EXEC_APPEND, va("exec cfg/triggersConfig%d.cfg\n", triggerMode[0]) );
  227. Cvar_SetValue( "in_useRumble", rumble[0] );
  228. Cvar_SetValue( "cl_autolevel", autolevel[0] );
  229. Cvar_SetValue( "cg_autoswitch", autoswitch[0] );
  230. Cvar_SetValue( "sensitivity", sensitivityX[0] );
  231. Cvar_SetValue( "sensitivityY", sensitivityY[0] );
  232. if( hotswapSP[0] >= 0 )
  233. Cvar_SetValue( "hotswap0", hotswapSP[0] );
  234. else
  235. Cvar_Set( "hotswap0", "" );
  236. if( hotswapSP[1] >= 0 )
  237. Cvar_SetValue( "hotswap1", hotswapSP[1] );
  238. else
  239. Cvar_Set( "hotswap1", "" );
  240. if( hotswapSP[2] >= 0 )
  241. Cvar_SetValue( "hotswap2", hotswapSP[2] );
  242. else
  243. Cvar_Set( "hotswap2", "" );
  244. Cvar_SetValue( "s_effects_volume", effectsVolume );
  245. Cvar_SetValue( "s_music_volume", musicVolume );
  246. Cvar_SetValue( "s_voice_volume", voiceVolume );
  247. Cvar_SetValue( "s_brightness_volume", brightness );
  248. extern void GLimp_SetGamma(float);
  249. GLimp_SetGamma(Cvar_VariableValue( "s_brightness_volume" ) / 5.0f);
  250. Cvar_SetValue( "g_subtitles", subtitles );
  251. }
  252. #ifdef XBOX_DEMO
  253. void XBSettings::RestoreDefaults( void )
  254. {
  255. version = SETTINGS_VERSION;
  256. // Defaults:
  257. invertAim[0] = invertAim[1] = false;
  258. thumbstickMode[0] = thumbstickMode[1] = 0;
  259. buttonMode[0] = buttonMode[1] = 0;
  260. triggerMode[0] = triggerMode[1] = 0;
  261. rumble[0] = rumble[1] = 1;
  262. autolevel[0] = autolevel[0] = 0;
  263. autoswitch[0] = autoswitch[1] = 1;
  264. sensitivityX[0] = sensitivityX[1] = 2.0f;
  265. sensitivityY[0] = sensitivityY[1] = 2.0f;
  266. hotswapSP[0] = hotswapSP[1] = hotswapSP[2] = -1;
  267. hotswapMP[0] = hotswapMP[1] = -1;
  268. hotswapMP[2] = hotswapMP[3] = -1;
  269. effectsVolume = 1.0f;
  270. musicVolume = 0.25f;
  271. voiceVolume = 1.0f;
  272. brightness = 6.0f;
  273. subtitles = 0;
  274. // Demo has no foreign audio, so we turn subtitles on if Dash language is FR/GE
  275. DWORD dwLang = XGetLanguage();
  276. if( dwLang == XC_LANGUAGE_FRENCH || dwLang == XC_LANGUAGE_GERMAN )
  277. subtitles = 1;
  278. voiceMode = 2;
  279. voiceMask = 0;
  280. appearOffline = 0;
  281. }
  282. #endif
  283. // Utility - signs the current contents of this XBSettings into the supplied struct:
  284. bool XBSettings::Sign( XCALCSIG_SIGNATURE *pSig )
  285. {
  286. // Start the signature:
  287. HANDLE hSig = XCalculateSignatureBegin( 0 );
  288. if( hSig == INVALID_HANDLE_VALUE )
  289. return false;
  290. // Build the signature
  291. if( XCalculateSignatureUpdate( hSig, (BYTE *) this, sizeof(*this) ) != ERROR_SUCCESS )
  292. return false;
  293. // Finish the signature:
  294. if( XCalculateSignatureEnd( hSig, pSig ) != ERROR_SUCCESS )
  295. return false;
  296. // Done!
  297. return true;
  298. }
  299. // Master switch for turning off settings when user picks
  300. // "Continue Without Saving"
  301. void XBSettings::Disable( void )
  302. {
  303. settingsDisabled = true;
  304. }
  305. bool XBSettings::IsDisabled( void )
  306. {
  307. return settingsDisabled;
  308. }