* improved quake2 support by added a quake2 boolean to the CGameDescription class...
[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(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(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(char *name, Str *pV, char *V);
114   void GetPref(char *name, int *pV, int V);
115   void GetPref(char *name, bool *pV, bool V);
116   void GetPref(char *name, float *pV, float V);
117   void GetPref(char *name, float *pV, float* V);
118   void GetPref(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 #if defined (__linux__) || defined (__APPLE__)
175   Str mUserPathPrefix; ///< prefix for ~/.q3a ~/.wolf init, only on *nix
176 #endif
177   Str mShaderPath; ///< the path in which to look for shaders
178   Str mShaderlist; ///< shaderlist file
179   float mTextureDefaultScale; ///< default scale (0.5 in q3, 1.0 in q1/q2, 0.25 in JK2 ..)
180   bool mEClassSingleLoad; ///< only load a single eclass definition file
181   bool mNoPatch; ///< this game doesn't support patch technology
182   Str mCaulkShader; ///< the shader to use for caulking
183   bool quake2; ///< set this to true to get quake2
184
185   CGameDescription() { mpDoc = NULL; }
186   /*!
187   \todo parse basic info from the node
188   user-friendly name of the game
189   essential parameters (such as the start dir)
190   */
191   CGameDescription(xmlDocPtr pDoc, const Str &GameFile);
192   virtual ~CGameDescription() { xmlFreeDoc(mpDoc); }
193
194   void Dump();
195 };
196
197 /*!
198 select games, copy editing assets and write out configuration files
199  */
200
201 #define Q3_PACK "Q3Pack"
202 #define URT_PACK "UrTPack"
203
204 class CGameInstall : public Dialog {
205 public:
206         CGameInstall();
207         void ScanGames();
208         void Run();
209         void BuildDialog();
210
211         enum gameType_e {
212                 GAME_NONE = 0,
213                 GAME_Q3 = 1,
214                 GAME_URT,
215                 GAME_WARSOW,
216                 GAME_COUNT
217         };
218
219 protected:
220         Str             m_strName;
221         Str             m_strMod;
222         Str             m_strEngine;
223         int             m_nComboSelect;
224
225         // maps from m_nComboSelect to the games
226         int     m_availGames[GAME_COUNT];
227 };
228
229 /*!
230 standalone dialog for games selection, and more generally global settings
231 */
232 class CGameDialog : public Dialog
233 {
234   GtkWidget *mFrame; ///< this is built on-demand first time it's used
235   GtkWidget *mTopBox; ///< top level box used to store the dialog frame, must unhook after modal use
236
237
238   /*!
239   global prefs storage
240   */
241   CXMLPropertyBag mGlobalPrefs;
242
243 #ifdef _WIN32
244   /*!
245   run from a network share
246   this one is not being saved out in prefs, since we need to know before we load prefs
247   we use a dummy file NETRUN_FILENAME as flag
248   all done with static stuff
249   */
250   static bool m_bNetRun;
251 #endif
252
253   bool m_bDoGameInstall;
254
255   CGameInstall mGameInstall;
256
257 protected:
258   
259   int m_nComboSelect; ///< intermediate int value for combo in dialog box
260
261 public:
262
263   /*! 
264   those settings are saved in the global prefs file 
265   I'm too lazy to wrap behind protected access, not sure this needs to be public
266   NOTE: those are preference settings. if you change them it is likely that you would
267   have to restart the editor for them to take effect
268   */
269   /*@{*/
270   /*!
271   what game has been selected
272   this is the name of the .game file
273   */
274   Str m_sGameFile;
275   /*!
276   auto-load the game on startup
277   this is linked to auto-load checkbox
278   */
279   bool m_bAutoLoadGame;
280   /*!
281   log console to radiant.log
282   m_bForceLogConsole is an obscure forced latching situation
283   */
284   bool m_bLogConsole;
285   bool m_bForceLogConsole;
286   /*@}*/
287
288   /*!
289   points somewhere in mGames, set once at startup
290   */
291   CGameDescription *m_pCurrentGameDescription;
292
293   /*!
294   the list of game descriptions we scanned from the game/ dir
295   */
296   list<CGameDescription *> mGames;
297
298   CGameDialog() {
299           mFrame = NULL;
300           m_pCurrentGameDescription = NULL;
301           m_bLogConsole = false;
302           m_bForceLogConsole = false;
303           m_bDoGameInstall = true;      // go through DoModal at least once
304   }
305   virtual ~CGameDialog(); 
306
307   void AddPacksURL( Str &s );
308     
309   /*!
310   intialize the game dialog, called at CPrefsDlg::Init
311   will scan for games, load prefs, and do game selection dialog if needed
312   */
313   void Init();
314
315   /*!
316   reset the global settings by removing the file
317   */
318   void Reset();
319
320   /*!
321   run the dialog UI for the list of games 
322   */
323   void DoGameDialog();
324
325   /*!
326         call out to the game installation dialog
327   */
328   void DoGameInstall();
329
330   /*!
331   Dialog API
332   this is only called when the dialog is built at startup for main engine select
333   */
334   void BuildDialog();
335   void UpdateData( bool retrieve );
336
337   /*!
338   construction of the dialog frame
339   this is the part to be re-used in prefs dialog
340   for the standalone dialog, we include this in a modal box
341   for prefs, we hook the frame in the main notebook
342   build the frame on-demand (only once)
343   */
344   GtkWidget *GetGlobalFrame();
345
346   /*!
347   global preferences subsystem
348   XML-based this time, hopefully this will generalize to other prefs
349   LoadPrefs has hardcoded defaults
350   NOTE: it may not be strictly 'CGameDialog' to put the global prefs here
351     could have named the class differently I guess
352   */
353   /*@{*/
354   void LoadPrefs(); ///< load from file into variables
355   void SavePrefs(); ///< save pref variables to file
356   /*@}*/
357
358   /*!
359   read or set netrun (check file)
360   \param retrieve 
361     if false, will check if netrun file is present and will set m_bNetRun
362     if true, will create/erase the netrun file depending on m_bNetRun
363     NOTE: this is not backwards, 'retrieve' means 'retrieve from settings dialog' - in terms of UI
364   */
365   static void UpdateNetrun(bool retrieve);
366   /*!
367   get current netrun setting
368   */
369   static bool GetNetrun();
370
371 private:
372   /*!
373   scan for .game files, load them
374   */
375   void ScanForGames();
376
377   /*!
378   inits g_PrefsDlg.m_global_rc_path
379   */
380   void InitGlobalPrefPath();
381
382   /*!
383   uses m_nComboItem to find the right mGames
384   */
385   CGameDescription *GameDescriptionForComboItem();
386
387   /*!
388         callback for the game install button
389   */
390   static void SInstallCallback( GtkWidget *widget, gpointer data );
391 };
392
393 typedef struct {
394   int nEntitySplit1;
395   int nEntitySplit2;
396   
397   window_position_t position;
398
399   window_position_t posEntityWnd;
400   window_position_t posMapInfoWnd;
401   window_position_t posCamWnd;
402   window_position_t posZWnd;
403   window_position_t posXYWnd;
404   window_position_t posXZWnd;
405   window_position_t posYZWnd;
406   window_position_t posPatchWnd;
407   window_position_t posSurfaceWnd;
408   window_position_t posEntityInfoWnd;
409
410   int nXYHeight;
411   int nZWidth;
412   int nXYWidth;
413   int nCamWidth;
414   int nCamHeight;
415   int nZFloatWidth;
416   int nState;
417 } windowPosInfo_t;
418
419 class PrefsDlg : public Dialog
420 {
421   
422 public:
423   /*!
424   local prefs file
425   */
426   CXMLPropertyBag mLocalPrefs;
427
428   // will enable/disable stuff according to the situation
429   void DoSensitivity();
430   void PreModal() { DoSensitivity(); }
431   
432   // enable/disable custom editor entry
433   void DoEditorSensitivity();
434   
435   /*!
436   this holds global level preferences
437   */
438   CGameDialog mGamesDialog;
439 protected:
440   // warning about old project files
441   bool m_bWarn;
442   list<CGameDescription *> mGames;
443   
444 public:
445   // last light intensity used in the CLightPrompt dialog, stored in registry
446   int m_iLastLightIntensity;
447   // these mirror what goes in the combo box
448   // see PrefDlg::m_nShader, tells wether to load NONE / COMMON or ALL shaders at parsing stage
449   enum {SHADER_NONE = 0, SHADER_COMMON, SHADER_ALL};
450
451   // Gef: updated preferences dialog
452   /*! Preference notebook page numbers */
453   enum {PTAB_FRONT = 0, PTAB_GAME_SETTINGS, PTAB_2D, PTAB_CAMERA, PTAB_TEXTURE, PTAB_LAYOUT, PTAB_MOUSE,
454         PTAB_EDITING, PTAB_STARTUP, PTAB_PATHS, PTAB_MISC, PTAB_BSPMONITOR} pref_tabs;
455   
456   GtkWidget *notebook;
457        
458   void UpdateTextureCompression();
459
460 #ifdef ATIHACK_812
461   void UpdateATIHack();
462 #endif
463         
464   void LoadPrefs();
465   void SavePrefs();
466   void LoadTexdefPref(texdef_t* pTexdef, char* pName);
467
468   PrefsDlg ();
469   virtual ~PrefsDlg ()
470   {
471     g_string_free (m_rc_path, true );
472     g_string_free (m_inipath, true );
473   }
474
475   /*!
476   path for global settings
477   win32: g_strAppPath
478   linux: ~/.radiant/<version>/
479   */
480   GString *m_global_rc_path;
481
482   /*!
483   path to per-game settings
484   used for various game dependant storage
485   win32: g_strGameToolsPath
486   linux: ~/.radiant/<version>/<gamename>/
487   */
488   GString *m_rc_path;
489
490   /*!
491   holds per-game settings
492   m_rc_path+"local.pref"
493   \todo FIXME at some point this should become XML property bag code too
494   */
495   GString *m_inipath;
496
497   // initialize the above paths
498   void Init();
499
500 #if 0
501   // DEPRECATED: use engine path from the current game description instead
502         // path to the top-level installation
503         Str     m_strEnginePath;
504   // name of executable
505   // quake2 quake3 etc
506         Str     m_strEngine;
507   // we use this Str to store the full path to the engine: m_strEnginePath + m_strEngine
508   // it's not stored in the registry or anything, just ued for display in prefs
509   Str   m_strPrefsDlgEngine;
510 #endif
511
512   // Dialog Data
513   int   m_nMouse;
514   MainFrame::EViewStyle m_nView;
515   bool  m_bTextureLock;
516   bool  m_bLoadLast;
517         // path to the project loaded at startup
518         // if g_PrefsDlg can't find the information in the ini file
519         // it will try to guess and eventually ask the user
520   Str   m_strLastProject;  
521   /*!
522   version of last loaded project file
523   says -1 if there's no version loaded
524   if it's a manually constructed project file, will be 0
525   otherwise the actual 'version' epair
526   */
527   int   m_nLastProjectVer;
528   Str   m_strLastMap;
529   bool  m_bInternalBSP;
530   bool  m_bRightClick;
531   bool  m_bSetGame;
532   bool  m_bAutoSave;
533   bool  m_bLoadLastMap;
534   bool  m_bTextureWindow;
535   bool  m_bSnapShots;
536   float m_fTinySize;
537   bool  m_bCleanTiny;
538   bool  m_bCamXYUpdate;
539   int   m_nCamDragMultiSelect;
540   bool  m_bCamDragMultiSelect;
541   bool  m_bCamFreeLook;
542   bool  m_bCamFreeLookStrafe;
543   bool  m_bCamInverseMouse;
544   bool  m_bCamDiscrete;
545   bool  m_bNewLightDraw;
546   Str   m_strPrefabPath;
547   int   m_nWhatGame;
548   bool  m_bALTEdge;
549   bool  m_bFaceColors;
550   bool  m_bXZVis;
551   bool  m_bYZVis;
552   bool  m_bZVis;
553   bool  m_bSizePaint;
554   bool  m_bDLLEntities;
555   bool  m_bRotateLock;
556   bool  m_bDetachableMenus;
557   bool  m_bPatchToolbar;
558   bool  m_bWideToolbar;
559   bool  m_bPluginToolbar;
560   bool  m_bNoClamp;
561         //++timo this is most likely broken, I don't know what it's supposed to do
562   Str   m_strUserPath;
563   int   m_nRotation;
564   bool  m_bChaseMouse;
565   bool  m_bTextureScrollbar;
566   bool  m_bDisplayLists;
567   bool  m_bAntialiasedPointsAndLines; // Fishman - Add antialiazed points and lines support. 09/03/00
568   bool  m_bShowShaders;
569   int   m_nShader;
570   bool  m_bNoStipple;
571   int   m_nUndoLevels;
572   bool  m_bVertexSplit;
573
574   int   m_nMouseButtons;
575   int   m_nAngleSpeed;
576   int   m_nMoveSpeed;
577   int   m_nAutoSave;
578   bool  m_bCubicClipping;
579   int   m_nCubicScale;
580   bool  m_bSelectCurves;
581   bool  m_bSelectModels;
582   int   m_nEntityShowState;
583   int   m_nTextureScale;
584   bool  m_bNormalizeColors;
585   bool  m_bSwitchClip;
586   bool  m_bSelectWholeEntities;
587   int   m_nTextureQuality;
588   bool  m_bGLLighting;
589   bool  m_bTexturesShaderlistOnly;
590   int   m_nSubdivisions;
591   bool  m_bFloatingZ;
592   bool  m_bLatchedFloatingZ;
593   // Gef: Kyro GL_POINT workaround
594   bool  m_bGlPtWorkaround;
595
596   // how many menus in the texture thing before we split?
597   int   m_nTextureMenuSplit;
598
599   // watch the BSP process through network connections
600   // true: trigger the BSP steps one by one and monitor them through the network
601   // false: create a BAT / .sh file and execute it. don't bother monitoring it.
602   bool  m_bWatchBSP;
603   // do we stop the compilation process if we come accross a leak?
604   bool  m_bLeakStop;
605   // timeout when beginning a step (in seconds)
606   // if we don't get a connection quick enough we assume something failed and go back to idling
607   int   m_iTimeout;
608   bool  m_bRunQuake;
609   // store prefs setting for automatic sleep mode activation
610   bool  m_bDoSleep;
611   
612   bool m_bClipCaulk;
613
614   // make the texture increments match the grid changes
615   bool m_bSnapTToGrid;
616
617   // try to fix the target/targetname conflicts when importing a map (default true)
618   bool m_bDoTargetFix;
619
620   // the increment step we use against the wheel mouse
621   int m_nWheelInc;
622
623 #ifdef _WIN32
624   // use the file associations to open files instead of builtin Gtk editor
625   bool m_bUseWin32Editor;
626 #else
627   // custom shader editor
628   bool m_bUseCustomEditor;
629   Str  m_strEditorCommand;  // this is the command executed
630 #endif
631
632 #ifdef _WIN32
633   bool m_bNativeGUI;
634   bool m_bStartOnPrimMon;
635 #endif
636
637   bool m_bPatchBBoxSelect;
638
639   // RR2DO2: latched data, for settings that require a restart. We don't want to set
640   // these directly in case users set them under preferences and then continue working
641   // with the editor.
642   MainFrame::EViewStyle m_nLatchedView;
643   int m_nMRUCount;
644   Str m_strMRUFiles[4];
645
646   windowPosInfo_t mWindowInfo;
647
648   bool  m_bLatchedDetachableMenus;
649   bool  m_bLatchedPatchToolbar;
650   bool  m_bLatchedWideToolbar;
651   bool  m_bLatchedPluginToolbar;
652   int   m_nLatchedShader;
653   int   m_nLatchedTextureQuality;
654
655   // RIANT
656   // texture compression format
657   int m_nTextureCompressionFormat;
658
659   int m_nLightRadiuses;
660   
661   bool m_bQ3Map2Texturing;
662
663 #ifdef ATIHACK_812
664         bool m_bGlATIHack;
665 #endif
666
667   void UpdateData (bool retrieve);
668
669   /*! Utility function for swapping notebook pages for tree list selections */
670   void showPrefPage(int prefpage);
671
672 protected:
673   /*! Scan for game description files and build a list */
674   void ScanForGames();
675
676   /*! Dialog API */
677   void BuildDialog ();
678   void PostModal (int code);
679 };
680
681 #endif // _PREFERENCES_H_