transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / radiant / preferences.h
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 #ifndef _PREFERENCES_H_\r
23 #define _PREFERENCES_H_\r
24 \r
25 #include "dialog.h"\r
26 #include "gtkr_list.h"\r
27 //#include "profile.h"\r
28 \r
29 #define MAX_TEXTURE_QUALITY 3\r
30 \r
31 enum PrefTypes_t\r
32 {\r
33   PREF_STR,\r
34   PREF_INT,\r
35   PREF_BOOL,\r
36   PREF_FLOAT,\r
37   PREF_VEC3,\r
38   PREF_WNDPOS,\r
39 };\r
40 \r
41 /*!\r
42 a preference assignment, name, type and pointer to value\r
43 we don't store the xmlNodePtr because the document itself can be thrown away upon any LoadPref\r
44 (see CGameDialog::UpdatePrefTree)\r
45 */\r
46 class CPrefAssignment\r
47 {\r
48 public:\r
49   Str mName;\r
50   PrefTypes_t mType;\r
51   void *mVal;\r
52 \r
53   CPrefAssignment(char *name, PrefTypes_t Type, void *Val)\r
54   {\r
55     mName = name; mType = Type; mVal = Val;\r
56   }\r
57   CPrefAssignment() { mVal = NULL; }\r
58   CPrefAssignment(const CPrefAssignment& ass);\r
59   virtual ~CPrefAssignment() { }\r
60   virtual CPrefAssignment& operator =(const CPrefAssignment& ass);\r
61 };\r
62 \r
63 \r
64 /*!\r
65 generic preferences storage class, using xml files\r
66 */\r
67 class CXMLPropertyBag\r
68 {\r
69 private:\r
70   /*!\r
71   local prefs file\r
72   */\r
73   xmlDocPtr mpDoc;\r
74   xmlNodePtr mpDocNode;\r
75 \r
76   /*!\r
77   prefs assignments (what pref name, what type, what variable)\r
78   */\r
79   list<CPrefAssignment> mPrefAssignments;\r
80 \r
81   /*!\r
82   name of file to load/save as\r
83   */\r
84   Str mStrFilename;\r
85 \r
86   /*!\r
87   store assignment in the property list if not already there\r
88   */\r
89   void PushAssignment(char *name, PrefTypes_t type, void *pV);\r
90 \r
91   /*!\r
92   find the xmlnode relating to the epair name\r
93   */\r
94   xmlNodePtr EpairForName(const char *name);\r
95 \r
96 public:\r
97   CXMLPropertyBag();\r
98   virtual ~CXMLPropertyBag() \r
99   {\r
100     if (InUse())\r
101       Clear();\r
102   };\r
103 \r
104   /*!\r
105   read a pref setting, if doesn't exist, will add it to the xml tree (using default value provided)\r
106   \arg name the name of the pref\r
107   \arg pV pointer to the value\r
108   \arg V default value\r
109   those functions will fill in the list of preferences assignments\r
110     (name, type and pointer to value)\r
111     this is used in UpdatePrefTree\r
112   */\r
113   void GetPref(char *name, Str *pV, char *V);\r
114   void GetPref(char *name, int *pV, int V);\r
115   void GetPref(char *name, bool *pV, bool V);\r
116   void GetPref(char *name, float *pV, float V);\r
117   void GetPref(char *name, float *pV, float* V);\r
118   void GetPref(char *name, window_position_t* pV, window_position_t V);\r
119 \r
120   /*!\r
121   returns whether or not the property bag is already open\r
122   */\r
123   qboolean InUse() { return (mpDoc != NULL); };\r
124 \r
125   /*!\r
126   unload the xml doc, and free the tree\r
127   */\r
128   void Clear();\r
129 \r
130   /*|\r
131   read data from our XML file\r
132   */\r
133   void ReadXMLFile(const char* pFilename);\r
134 \r
135   /*|\r
136   write out the property bag to an XML data file\r
137   return is success/fail\r
138   */\r
139   qboolean WriteXMLFile(const char* pFilename);\r
140 \r
141   /*!\r
142   update the xml tree with data form the property list, usually in preparation for a write\r
143   */\r
144   void UpdatePrefTree();\r
145 \r
146   /*!\r
147   did the file have any data or not?\r
148   */\r
149   qboolean mbEmpty;\r
150 };\r
151 \r
152 /*!\r
153 holds information for a given game\r
154 I'm a bit unclear on that still\r
155 it holds game specific configuration stuff\r
156 such as base names, engine names, some game specific features to activate in the various modules\r
157 it is not strictly a prefs thing since the user is not supposed to edit that (unless he is hacking\r
158 support for a new game)\r
159 \r
160 what we do now is fully generate the information for this during the setup. We might want to\r
161 generate a piece that just says "the game pack is there", but put the rest of the config somwhere\r
162 else (i.e. not generated, copied over during setup .. for instance in the game tools directory)\r
163 */\r
164 class CGameDescription\r
165 {\r
166 public:\r
167   xmlDocPtr mpDoc; ///< the game description xml tree\r
168   Str mGameToolsPath; ///< the explicit path to the game-dependent modules\r
169   Str mGameName; ///< name of the game used in dialogs\r
170   Str mGameFile; ///< the .game file that describes this game\r
171   Str mBaseGame; ///< basegame directory\r
172   Str mEnginePath; ///< path to the engine\r
173   Str mEngine; ///< engine name\r
174 #if defined (__linux__) || defined (__APPLE__)\r
175   Str mUserPathPrefix; ///< prefix for ~/.q3a ~/.wolf init, only on *nix\r
176 #endif\r
177   Str mShaderPath; ///< the path in which to look for shaders\r
178   Str mShaderlist; ///< shaderlist file\r
179   float mTextureDefaultScale; ///< default scale (0.5 in q3, 1.0 in q1/q2, 0.25 in JK2 ..)\r
180   bool mEClassSingleLoad; ///< only load a single eclass definition file\r
181   bool mNoPatch; ///< this game doesn't support patch technology\r
182   Str mCaulkShader; ///< the shader to use for caulking\r
183 \r
184   CGameDescription() { mpDoc = NULL; }\r
185   /*!\r
186   \todo parse basic info from the node\r
187   user-friendly name of the game\r
188   essential parameters (such as the start dir)\r
189   */\r
190   CGameDescription(xmlDocPtr pDoc, const Str &GameFile);\r
191   virtual ~CGameDescription() { xmlFreeDoc(mpDoc); }\r
192 \r
193   void Dump();\r
194 };\r
195 \r
196 /*!\r
197 standalone dialog for games selection, and more generally global settings\r
198 */\r
199 class CGameDialog : public Dialog\r
200 {\r
201   GtkWidget *mFrame; ///< this is built on-demand first time it's used\r
202   GtkWidget *mTopBox; ///< top level box used to store the dialog frame, must unhook after modal use\r
203 \r
204 \r
205   /*!\r
206   global prefs storage\r
207   */\r
208   CXMLPropertyBag mGlobalPrefs;\r
209 \r
210 #ifdef _WIN32\r
211   /*!\r
212   run from a network share\r
213   this one is not being saved out in prefs, since we need to know before we load prefs\r
214   we use a dummy file NETRUN_FILENAME as flag\r
215   all done with static stuff\r
216   */\r
217   static bool m_bNetRun;\r
218 #endif\r
219 \r
220 protected:\r
221   \r
222   int m_nComboSelect; ///< intermediate int value for combo in dialog box\r
223 \r
224 public:\r
225 \r
226   /*! \r
227   those settings are saved in the global prefs file \r
228   I'm too lazy to wrap behind protected access, not sure this needs to be public\r
229   NOTE: those are preference settings. if you change them it is likely that you would\r
230   have to restart the editor for them to take effect\r
231   */\r
232   /*@{*/\r
233   /*!\r
234   what game has been selected\r
235   this is the name of the .game file\r
236   */\r
237   Str m_sGameFile;\r
238   /*!\r
239   auto-load the game on startup\r
240   this is linked to auto-load checkbox\r
241   */\r
242   bool m_bAutoLoadGame;\r
243   /*!\r
244   log console to radiant.log\r
245   m_bForceLogConsole is an obscure forced latching situation\r
246   */\r
247   bool m_bLogConsole;\r
248   bool m_bForceLogConsole;\r
249   /*@}*/\r
250 \r
251   /*!\r
252   points somewhere in mGames, set once at startup\r
253   */\r
254   CGameDescription *m_pCurrentGameDescription;\r
255 \r
256   /*!\r
257   the list of game descriptions we scanned from the game/ dir\r
258   */\r
259   list<CGameDescription *> mGames;\r
260 \r
261   CGameDialog() { mFrame = NULL; m_pCurrentGameDescription = NULL; m_bLogConsole = false; m_bForceLogConsole = false; }\r
262   virtual ~CGameDialog(); \r
263 \r
264   void AddPacksURL(Str &s);  \r
265     \r
266   /*!\r
267   intialize the game dialog, called at CPrefsDlg::Init\r
268   will scan for games, load prefs, and do game selection dialog if needed\r
269   */\r
270   void Init();\r
271 \r
272   /*!\r
273   reset the global settings by removing the file\r
274   */\r
275   void Reset();\r
276 \r
277   /*!\r
278   run the dialog UI for the list of games \r
279   */\r
280   void DoGameDialog();\r
281 \r
282   /*!\r
283   Dialog API\r
284   this is only called when the dialog is built at startup for main engine select\r
285   */\r
286   void BuildDialog ();\r
287   void UpdateData (bool retrieve);\r
288 \r
289   /*!\r
290   construction of the dialog frame\r
291   this is the part to be re-used in prefs dialog\r
292   for the standalone dialog, we include this in a modal box\r
293   for prefs, we hook the frame in the main notebook\r
294   build the frame on-demand (only once)\r
295   */\r
296   GtkWidget *GetGlobalFrame();\r
297 \r
298   /*!\r
299   global preferences subsystem\r
300   XML-based this time, hopefully this will generalize to other prefs\r
301   LoadPrefs has hardcoded defaults\r
302   NOTE: it may not be strictly 'CGameDialog' to put the global prefs here\r
303     could have named the class differently I guess\r
304   */\r
305   /*@{*/\r
306   void LoadPrefs(); ///< load from file into variables\r
307   void SavePrefs(); ///< save pref variables to file\r
308   /*@}*/\r
309 \r
310   /*!\r
311   read or set netrun (check file)\r
312   \param retrieve \r
313     if false, will check if netrun file is present and will set m_bNetRun\r
314     if true, will create/erase the netrun file depending on m_bNetRun\r
315     NOTE: this is not backwards, 'retrieve' means 'retrieve from settings dialog' - in terms of UI\r
316   */\r
317   static void UpdateNetrun(bool retrieve);\r
318   /*!\r
319   get current netrun setting\r
320   */\r
321   static bool GetNetrun();\r
322 \r
323 private:\r
324   /*!\r
325   scan for .game files, load them\r
326   */\r
327   void ScanForGames();\r
328 \r
329   /*!\r
330   inits g_PrefsDlg.m_global_rc_path\r
331   */\r
332   void InitGlobalPrefPath();\r
333 \r
334   /*!\r
335   uses m_nComboItem to find the right mGames\r
336   */\r
337   CGameDescription *GameDescriptionForComboItem();\r
338 };\r
339 \r
340 typedef struct {\r
341   int nEntitySplit1;\r
342   int nEntitySplit2;\r
343   \r
344   window_position_t position;\r
345 \r
346   window_position_t posEntityWnd;\r
347   window_position_t posMapInfoWnd;\r
348   window_position_t posCamWnd;\r
349   window_position_t posZWnd;\r
350   window_position_t posXYWnd;\r
351   window_position_t posXZWnd;\r
352   window_position_t posYZWnd;\r
353   window_position_t posPatchWnd;\r
354   window_position_t posSurfaceWnd;\r
355   window_position_t posEntityInfoWnd;\r
356 \r
357   int nXYHeight;\r
358   int nZWidth;\r
359   int nXYWidth;\r
360   int nCamWidth;\r
361   int nCamHeight;\r
362   int nZFloatWidth;\r
363   int nState;\r
364 } windowPosInfo_t;\r
365 \r
366 class PrefsDlg : public Dialog\r
367 {\r
368   \r
369 public:\r
370   /*!\r
371   local prefs file\r
372   */\r
373   CXMLPropertyBag mLocalPrefs;\r
374 \r
375   // will enable/disable stuff according to the situation\r
376   void DoSensitivity();\r
377   void PreModal() { DoSensitivity(); }\r
378   \r
379   // enable/disable custom editor entry\r
380   void DoEditorSensitivity();\r
381   \r
382   /*!\r
383   this holds global level preferences\r
384   */\r
385   CGameDialog mGamesDialog;\r
386 protected:\r
387   // warning about old project files\r
388   bool m_bWarn;\r
389   list<CGameDescription *> mGames;\r
390   \r
391 public:\r
392   // last light intensity used in the CLightPrompt dialog, stored in registry\r
393   int m_iLastLightIntensity;\r
394   // these mirror what goes in the combo box\r
395   // see PrefDlg::m_nShader, tells wether to load NONE / COMMON or ALL shaders at parsing stage\r
396   enum {SHADER_NONE = 0, SHADER_COMMON, SHADER_ALL};\r
397 \r
398   // Gef: updated preferences dialog\r
399   /*! Preference notebook page numbers */\r
400   enum {PTAB_FRONT = 0, PTAB_GAME_SETTINGS, PTAB_2D, PTAB_CAMERA, PTAB_TEXTURE, PTAB_LAYOUT, PTAB_MOUSE,\r
401         PTAB_EDITING, PTAB_STARTUP, PTAB_PATHS, PTAB_MISC, PTAB_BSPMONITOR} pref_tabs;\r
402   \r
403   GtkWidget *notebook;\r
404        \r
405   void UpdateTextureCompression();\r
406 \r
407 #ifdef ATIHACK_812\r
408   void UpdateATIHack();\r
409 #endif\r
410         \r
411   void LoadPrefs();\r
412   void SavePrefs();\r
413   void LoadTexdefPref(texdef_t* pTexdef, char* pName);\r
414 \r
415   PrefsDlg ();\r
416   virtual ~PrefsDlg ()\r
417   {\r
418     g_string_free (m_rc_path, true );\r
419     g_string_free (m_inipath, true );\r
420   }\r
421 \r
422   /*!\r
423   path for global settings\r
424   win32: g_strAppPath\r
425   linux: ~/.radiant/<version>/\r
426   */\r
427   GString *m_global_rc_path;\r
428 \r
429   /*!\r
430   path to per-game settings\r
431   used for various game dependant storage\r
432   win32: g_strGameToolsPath\r
433   linux: ~/.radiant/<version>/<gamename>/\r
434   */\r
435   GString *m_rc_path;\r
436 \r
437   /*!\r
438   holds per-game settings\r
439   m_rc_path+"local.pref"\r
440   \todo FIXME at some point this should become XML property bag code too\r
441   */\r
442   GString *m_inipath;\r
443 \r
444   // initialize the above paths\r
445   void Init();\r
446 \r
447 #if 0\r
448   // DEPRECATED: use engine path from the current game description instead\r
449         // path to the top-level installation\r
450         Str     m_strEnginePath;\r
451   // name of executable\r
452   // quake2 quake3 etc\r
453         Str     m_strEngine;\r
454   // we use this Str to store the full path to the engine: m_strEnginePath + m_strEngine\r
455   // it's not stored in the registry or anything, just ued for display in prefs\r
456   Str   m_strPrefsDlgEngine;\r
457 #endif\r
458 \r
459   // Dialog Data\r
460   int   m_nMouse;\r
461   MainFrame::EViewStyle m_nView;\r
462   bool  m_bTextureLock;\r
463   bool  m_bLoadLast;\r
464         // path to the project loaded at startup\r
465         // if g_PrefsDlg can't find the information in the ini file\r
466         // it will try to guess and eventually ask the user\r
467   Str   m_strLastProject;  \r
468   /*!\r
469   version of last loaded project file\r
470   says -1 if there's no version loaded\r
471   if it's a manually constructed project file, will be 0\r
472   otherwise the actual 'version' epair\r
473   */\r
474   int   m_nLastProjectVer;\r
475   Str   m_strLastMap;\r
476   bool  m_bInternalBSP;\r
477   bool  m_bRightClick;\r
478   bool  m_bSetGame;\r
479   bool  m_bAutoSave;\r
480   bool  m_bLoadLastMap;\r
481   bool  m_bTextureWindow;\r
482   bool  m_bSnapShots;\r
483   float m_fTinySize;\r
484   bool  m_bCleanTiny;\r
485   bool  m_bCamXYUpdate;\r
486   int   m_nCamDragMultiSelect;\r
487   bool  m_bCamDragMultiSelect;\r
488   bool  m_bCamFreeLook;\r
489   bool  m_bCamFreeLookStrafe;\r
490   bool  m_bCamInverseMouse;\r
491   bool  m_bCamDiscrete;\r
492   bool  m_bNewLightDraw;\r
493   Str   m_strPrefabPath;\r
494   int   m_nWhatGame;\r
495   bool  m_bALTEdge;\r
496   bool  m_bFaceColors;\r
497   bool  m_bXZVis;\r
498   bool  m_bYZVis;\r
499   bool  m_bZVis;\r
500   bool  m_bSizePaint;\r
501   bool  m_bDLLEntities;\r
502   bool  m_bRotateLock;\r
503   bool  m_bDetachableMenus;\r
504   bool  m_bPatchToolbar;\r
505   bool  m_bWideToolbar;\r
506   bool  m_bPluginToolbar;\r
507   bool  m_bNoClamp;\r
508         //++timo this is most likely broken, I don't know what it's supposed to do\r
509   Str   m_strUserPath;\r
510   int   m_nRotation;\r
511   bool  m_bChaseMouse;\r
512   bool  m_bTextureScrollbar;\r
513   bool  m_bDisplayLists;\r
514   bool  m_bAntialiasedPointsAndLines; // Fishman - Add antialiazed points and lines support. 09/03/00\r
515   bool  m_bShowShaders;\r
516   int   m_nShader;\r
517   bool  m_bNoStipple;\r
518   int   m_nUndoLevels;\r
519   bool  m_bVertexSplit;\r
520 \r
521   int   m_nMouseButtons;\r
522   int   m_nAngleSpeed;\r
523   int   m_nMoveSpeed;\r
524   int   m_nAutoSave;\r
525   bool  m_bCubicClipping;\r
526   int   m_nCubicScale;\r
527   bool  m_bSelectCurves;\r
528   bool  m_bSelectModels;\r
529   int   m_nEntityShowState;\r
530   int   m_nTextureScale;\r
531   bool  m_bNormalizeColors;\r
532   bool  m_bSwitchClip;\r
533   bool  m_bSelectWholeEntities;\r
534   int   m_nTextureQuality;\r
535   bool  m_bGLLighting;\r
536   bool  m_bTexturesShaderlistOnly;\r
537   int   m_nSubdivisions;\r
538   bool  m_bFloatingZ;\r
539   bool  m_bLatchedFloatingZ;\r
540   // Gef: Kyro GL_POINT workaround\r
541   bool  m_bGlPtWorkaround;\r
542 \r
543   // how many menus in the texture thing before we split?\r
544   int   m_nTextureMenuSplit;\r
545 \r
546   // watch the BSP process through network connections\r
547   // true: trigger the BSP steps one by one and monitor them through the network\r
548   // false: create a BAT / .sh file and execute it. don't bother monitoring it.\r
549   bool  m_bWatchBSP;\r
550   // do we stop the compilation process if we come accross a leak?\r
551   bool  m_bLeakStop;\r
552   // timeout when beginning a step (in seconds)\r
553   // if we don't get a connection quick enough we assume something failed and go back to idling\r
554   int   m_iTimeout;\r
555   bool  m_bRunQuake;\r
556   // store prefs setting for automatic sleep mode activation\r
557   bool  m_bDoSleep;\r
558   \r
559   bool m_bClipCaulk;\r
560 \r
561   // make the texture increments match the grid changes\r
562   bool m_bSnapTToGrid;\r
563 \r
564   // try to fix the target/targetname conflicts when importing a map (default true)\r
565   bool m_bDoTargetFix;\r
566 \r
567   // the increment step we use against the wheel mouse\r
568   int m_nWheelInc;\r
569 \r
570 #ifdef _WIN32\r
571   // use the file associations to open files instead of builtin Gtk editor\r
572   bool m_bUseWin32Editor;\r
573 #else\r
574   // custom shader editor\r
575   bool m_bUseCustomEditor;\r
576   Str  m_strEditorCommand;  // this is the command executed\r
577 #endif\r
578 \r
579 #ifdef _WIN32\r
580   bool m_bNativeGUI;\r
581   bool m_bStartOnPrimMon;\r
582 #endif\r
583 \r
584   bool m_bPatchBBoxSelect;\r
585 \r
586   // RR2DO2: latched data, for settings that require a restart. We don't want to set\r
587   // these directly in case users set them under preferences and then continue working\r
588   // with the editor.\r
589   MainFrame::EViewStyle m_nLatchedView;\r
590   int m_nMRUCount;\r
591   Str m_strMRUFiles[4];\r
592 \r
593   windowPosInfo_t mWindowInfo;\r
594 \r
595   bool  m_bLatchedDetachableMenus;\r
596   bool  m_bLatchedPatchToolbar;\r
597   bool  m_bLatchedWideToolbar;\r
598   bool  m_bLatchedPluginToolbar;\r
599   int   m_nLatchedShader;\r
600   int   m_nLatchedTextureQuality;\r
601 \r
602   // RIANT\r
603   // texture compression format\r
604   int m_nTextureCompressionFormat;\r
605 \r
606   int m_nLightRadiuses;\r
607   \r
608   bool m_bQ3Map2Texturing;\r
609 \r
610 #ifdef ATIHACK_812\r
611         bool m_bGlATIHack;\r
612 #endif\r
613 \r
614   void UpdateData (bool retrieve);\r
615 \r
616   /*! Utility function for swapping notebook pages for tree list selections */\r
617   void showPrefPage(int prefpage);\r
618 \r
619 protected:\r
620   /*! Scan for game description files and build a list */\r
621   void ScanForGames();\r
622 \r
623   /*! Dialog API */\r
624   void BuildDialog ();\r
625   void PostModal (int code);\r
626 };\r
627 \r
628 #endif // _PREFERENCES_H_\r