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